//============================================================================================
/**
 * @file  bag_main.c
 * @brief バッグ画面処理
 * @author  Hiroyuki Nakamura
 * @date  06.04.17
 */
//============================================================================================

#include "common.h"
#include "gflib/touchpanel.h"
#include "system/gamedata.h"
#include "system/procsys.h"
#include "system/fontproc.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/window.h"
#include "system/pm_str.h"
#include "system/pmfprint.h"
#include "system/lib_pack.h"
#include "system/snd_tool.h"
#include "system/arc_tool.h"
#include "system/arc_util.h"
#include "system/clact_util.h"
#include "system/clact_tool.h"
#include "system/render_oam.h"
#include "system/brightness.h"
#include "system/buflen.h"
#include "system/msgdata.h"
#include "system/wordset.h"
#include "system/numfont.h"
#include "system/mystatus.h"
#include "system/wipe.h"
#include "savedata/config.h"
#include "savedata/encount.h"
#include "savedata/vidro_type.h"
#include "itemtool/item.h"
#include "itemtool/myitem.h"
#include "itemtool/itemuse_def.h"
#include "msgdata/msg.naix"
#include "msgdata/msg_bag.h"
#include "msgdata/msg_common_scr.h"
#include "field/itemuse.h"
#include "application/app_tool.h"
#include "communication/wm_icon.h"
#include "bag_camera.dat"       // ポケットごとのカメラ位置・エッジカラーテーブル

#include "../../field/map_mode.h"

//
// 2009/10/16セーブデータ調査用に作成したバッグデータ閲覧・修正処理
// どうぐID０で1個というデータが存在した事があった
//
//#define FIX_BAG_DATA
//#define PRINT_BAG_DATA

#define BAG_MAIN_H_GLOBAL
#include "application/bag.h"
#include "bag_main.h"
#include "bag_obj.h"
#include "bag_bmp.h"
#include "bag_snd_def.h"
#include "bag_gra.naix"

#ifdef PM_DEBUG
// 定義を有効にする事で上画面のモデリングが動かせるようになる
//#define DEBUG_CAMERA
#endif


//============================================================================================
//  定数定義
//============================================================================================
// メインシーケンス
enum {
  SEQ_IN = 0,   // 開始フェードイン
  SEQ_MAIN,   // アイテム選択
  SEQ_PAGE,   // ページ切り替え
  SEQ_IREKAE,   // 入れ替え選択
  SEQ_MENU,   // メニュー


  SEQ_ITEM_SUB_MAIN,    // メニュー「すてる」個数選択
  SEQ_ITEM_SUB_ENTER,
  SEQ_ITEM_SUB_CANCEL,
  SEQ_ITEM_SUB_YN_INIT, // メニュー「すてる」はい・いいえ初期化
  SEQ_ITEM_SUB_YN_SEL,  // メニュー「すてる」はい・いいえ
  SEQ_ITEM_SUB_CMP,   // メニュー「すてる」完了
  SEQ_ITEM_SUB_RET,   // メニュー「すてる」メッセージ終了待ち＆ボタン待ち -> メインへ

  SEQ_ITEM_ERR_WAIT,  // アイテム使用失敗

  SEQ_BAG_ITEMUSE,  // バッグ内アイテム使用

  SEQ_ITEMSET_MAIN, // ポケモンリスト「もたせる」アイテム選択
  SEQ_ITEMSET_ERR,  // ポケモンリスト「もたせる」失敗

  SEQ_SALE_MAIN,    // 「売る」モードアイテム選択
  SEQ_SALE_NUM_INIT,  // 「売る」モード個数選択初期化
  SEQ_SALE_NUM_SEL, // 「売る」モード個数選択
  SEQ_SALE_NUM_ENTER,
  SEQ_SALE_NUM_CANCEL,
  SEQ_SALE_YN_INIT, // 「売る」はい・いいえ初期化
  SEQ_SALE_YN_SEL,  // 「売る」はい・いいえ
  SEQ_SALE_CMP,   // 「売る」完了
  SEQ_SALE_RET,   // 「売る」メッセージ終了待ち＆ボタン待ち -> メインへ
  SEQ_ITEM_REGIST_ERR,

  SEQ_KINOMISEL_MAIN, // 木の実関連選択処理

  SEQ_MENU_INIT,
  SEQ_MENU_CANCEL,
  SEQ_MENU_SELECT,

  SEQ_LIST_ADD,
  SEQ_LIST_SUB,

  SEQ_IREKAE_CANCEL,
  SEQ_IREKAE_COMP,

  SEQ_SALE_MENU_INIT,

  SEQ_BUTTON_ANM,

  SEQ_OUT_SET,
  SEQ_OUT,      // フェードアウト
};

#define WIPE_COUNT_M  ( 192 )   // 上画面のウィンドウエフェクトカウンタの最大値
#define WIPE_COUNT_S  ( 384 )   // 下画面のウィンドウエフェクトカウンタの最大値
#define WIPE_SPEED    ( 16 )    // ウィンドウエフェクトスピード
#define VCOUNT_MAX    ( 262 )   // Vカウンタ最大値
// ウィンドウのマスク
#define WIPE_MASK   ( GX_WND_PLANEMASK_BG0 | GX_WND_PLANEMASK_BG1 | \
              GX_WND_PLANEMASK_BG2 | GX_WND_PLANEMASK_BG3 | \
              GX_WND_PLANEMASK_OBJ )

// アイテムリスト選択
enum {
  LIST_SEL_NONE = 0,  // 選択中
  LIST_SEL_ITEM,    // アイテムを選択
  LIST_SEL_CHANGE,  // 入れ替え
  LIST_SEL_CANCEL   // キャンセル
};

enum {
  BAG_PAGE_NORMAL=0,
  BAG_PAGE_INSERT,
  BAG_PAGE_SELECT,
  BAG_PAGE_SUB,
  BAG_PAGE_SALE,
};

enum {
  TOUCH_MODE_NORMAL=0,  // 通常時
  TOUCH_MODE_SELECT,    // どうぐ選択後の選択肢表示
  TOUCH_MODE_CHANGE,    // どうぐ入れ替え時
  TOUCH_MODE_NUMBER,    // 捨てる数値入力時
  TOUCH_MODE_SALE_NUMBER,   // 売る数値入力時
};

typedef int (*seqFunc)(BAG_WORK*);  // シーケンス関数ポインタ型


#define ICONPUT_SCRN_PX   ( 0 )   // アイテムアイコンを表示する背景X座標
#define ICONPUT_SCRN_PY   ( 18 )    // アイテムアイコンを表示する背景Y座標
#define ICONPUT_SCRN_SX   ( 5 )   // アイテムアイコンを表示する背景Xサイズ
#define ICONPUT_SCRN_SY   ( 5 )   // アイテムアイコンを表示する背景Yサイズ


#define LIST_PX_NORMAL    ( 0 )   // アイテムリストの表示X座標（通常）
#define LIST_PX_WAZAMACHINE ( 32 )    // アイテムリストの表示X座標（技マシン）

#define SUB_ENTER_PX    ( 13 )    // 下画面の決定ボタンのスクリーン書き換えX座標
#define SUB_ENTER_PY    ( 7 )   // 下画面の決定ボタンのスクリーン書き換えY座標
#define SUB_ENTER_SX    ( 6 )   // 下画面の決定ボタンのスクリーン書き換えXサイズ
#define SUB_ENTER_SY    ( 6 )   // 下画面の決定ボタンのスクリーン書き換えYサイズ
#define SUB_ENTER_CGX   ( 0x276)  // 下画面の決定ボタンのキャラ番号
#define SUB_ENTER_PAL   ( 3 )   // 下画面の決定ボタンのパレット

#define SUB_ENTER_EFF_X   ( 128 )   // 下画面の決定ボタンのエフェクト表示X座標
#define SUB_ENTER_EFF_Y   ( 80 )    // 下画面の決定ボタンのエフェクト表示Y座標

#define SUB_WHEEL_CX  ( 128 )   // 下画面のホイールの中心X座標
#define SUB_WHEEL_CY  ( 80 )    // 下画面のホイールの中心Y座標
#define SUB_WHEEL_R   ( 80 )    // 下画面のホイールの半径

#define SUB_WHEEL_REG ( 2 )   // 下画面のホイールのグラフィック回転補正

#define WHEEL_ROT_LIST  ( 36 )    // 下画面ホイールで一周でリストが動くカウント
#define WHEEL_ROT_MENU  ( 18 )    // 下画面ホイールで一周でメニューが動くカウント

#define CAMERA_MOVE_FRAME ( 7 ) // カメラが移動するフレーム数
#define CAMERA_NO_MOVE    ( -1 )  // カメラ移動が発生しないインデックス値

enum{
  CURSORPOS_POCKET0=0,
  CURSORPOS_POCKET1,
  CURSORPOS_POCKET2,
  CURSORPOS_POCKET3,
  CURSORPOS_POCKET4,
  CURSORPOS_POCKET5,
  CURSORPOS_POCKET6,
  CURSORPOS_POCKET7,

  CURSORPOS_ITEM0,
  CURSORPOS_ITEM1,
  CURSORPOS_ITEM2,
  CURSORPOS_ITEM3,
  CURSORPOS_ITEM4,
  CURSORPOS_ITEM5,

  CURSORPOS_SUBPAGE,
  CURSORPOS_ADDPAGE,

  CURSORPOS_END,

  CURSORPOS_POCKETS,  // 移動の際に現在のポケットにカーソルを移動させるための定義
};

typedef struct{
  u8 up,down,left,right;
}ARROW4_TBL;

// ボタンアニメ定義
enum {
  BUTTON_ANM_MODE_PAL = 0,  // パレットアニメ
  BUTTON_ANM_MODE_ANM,    // セルアニメ
};


// どうぐ選択時のカーソル移動テーブル
//  0    1
//  2    3     4
//
static const ARROW4_TBL select_cursor_tbl[]={
  {2, 2, 1, 1,},
  {3, 3, 0, 0,},
  {0, 0, 4, 3,},
  {1, 1, 2, 4,},
  {4, 4, 3, 2,},
};

static u8 select_cursor_pos_tbl[]={
  17,18,19, 20, 16,
};


// カーソル移動そのもののテーブル
// 0 1 2 3 4 5 6 7
//
//    8       9
//   10      11
//   12      13
//
// 14  15       16

static const ARROW4_TBL _key_table[]={
  { 12,  8, 7,  1,  },  // 上の列の８こ
  { 12,  8, 0,  2,  },
  { 12,  8, 1,  3,  },
  { 12,  8, 2,  4,  },
  { 16,  9, 3,  5,  },
  { 16,  9, 4,  6,  },
  { 16,  9, 5,  7,  },
  { 16,  9, 6,  0,  },

  {  CURSORPOS_POCKETS,   10,   14,   9,  },    // 真ん中の６個
  {  CURSORPOS_POCKETS,   11,   8,    15,   },
  {  8, 12,14, 11, },
  {  9, 13,10, 15, },
  { 10, CURSORPOS_POCKETS,14, 13, },
  { 11, 16,12, 15, },

  { 12,  CURSORPOS_POCKETS,16, 16, },   // 下の３個
  { 12,  CURSORPOS_POCKETS,16, 16, },
  { 13,  CURSORPOS_POCKETS,16, 16, },
};


static const ARROW4_TBL move_cursor_tbl[]={
  {  12,  10, 14,  9, },    // 真ん中の６個
  {  16,  11,  8, 15, },
  {  8,   12, 14, 11, },
  {  9,   13, 10, 15, },
  { 10,    8, 14, 13, },
  { 11,   16, 12, 15, },

  { 12,   8,16, 16, },    // 下の３個
  { 12,   8,16, 16, },
  { 13,   9,16, 16, },

};

//============================================================================================
//  プロトタイプ宣言
//============================================================================================
static void BAG_SaveDataGet( BAG_WORK * wk );
static void BagVBlank(void * work);
static void BagVramBankSet(void);
static void BagBgSet( GF_BGL_INI * ini );
static void BagBgExit( GF_BGL_INI * ini );
static void BagBgGraphicSet( BAG_WORK * wk );
static u8 PocketControl( BAG_WORK * wk );
static int MenuControl( BAG_WORK * wk );
static void ItemListDataMake( BAG_WORK * wk );
static void ItemListParamReset( s16 * scr, u16 * pos, u8 buf_max );
static void ItemListParamResetAll( BAG_WORK * wk );
static void ItemListCurPosReset( s16 * scr, u16 * pos, u8 buf_max, u8 list_max );
static void ItemListCurPosResetAll( BAG_WORK * wk );
static void ItemListSet( BAG_WORK * wk, s16 scr, u16 pos );
static void ItemListExit( BAG_WORK * wk );
static void ItemInfoPrint( u16 id, s8 wait );
static void CellActorTest(void);
static void PocketDataInit( BAG_WORK * wk );
static u8 PocketCursorObjPXGet( BAG_WORK * wk, u8 poke );
static void PocketIconXmake( BAG_WORK * wk );
static u32 TouchButtonControl( BAG_WORK * wk, int mode );
static int SubPokeButtonEndCheck( BAG_WORK * wk );
static void ItemMenuExit( BAG_WORK * wk );
static u8 PocketCursorMove( BAG_WORK * wk );
static u8 ItemChangeCheck( BAG_WORK * wk );
static void ItemChangeInit( BAG_WORK * wk );
static int ItemChangeMain( BAG_WORK * wk );
static int ItemChangeComp( BAG_WORK * wk );
static int ItemChangeEnd( BAG_WORK * wk );
static void ItemChgCursorChg( BAG_WORK * wk );
static void ItemIconChange( BAG_WORK * wk, u16 item );
static void PocketChangeInitKey( BAG_WORK * wk );
static void PocketChangeInitTp( BAG_WORK * wk );
static void PocketChangeInit( BAG_WORK * wk );
static u8 PocketChange( BAG_WORK * wk );
static u8 PocketChangeReset( BAG_WORK * wk );
static u8 PocketCursorMove( BAG_WORK * wk );
static void MsgManCreate( BAG_WORK * wk );
static void PocketNameScreenPut( BAG_WORK * wk );
static void ItemMenuMake( BAG_WORK * wk );
static void ItemListStrAlloc( BAG_WORK * wk );
static void ItemListStrFree( BAG_WORK * wk );
static int Bag_MenuUse( BAG_WORK * wk );
static int MainSeqFunc( BAG_WORK * wk );
static int SaleMainSeq( BAG_WORK * wk );
static int SaleRetSeq( BAG_WORK * wk );
static int SaleNumInitSeq( BAG_WORK * wk );
static int SaleNumSelSeq( BAG_WORK * wk );
static int SaleYesNoInitSeq( BAG_WORK * wk );
static int SaleYesNoSelectSeq( BAG_WORK * wk );
static int SaleCmpSeq( BAG_WORK * wk );
static int ItemErrWaitSeq( BAG_WORK * wk );
static int Bag_MenuTag( BAG_WORK * wk );
static int Bag_MenuKettei( BAG_WORK * wk );
static int Bag_MenuSub( BAG_WORK * wk );
static int Bag_MenuSubMain( BAG_WORK * wk );
static int Bag_MenuSubNumEnter( BAG_WORK * wk );
static int Bag_MenuSubNumCancel( BAG_WORK * wk );
static int Bag_MenuSubYesNoInitSeq( BAG_WORK * wk );
static int Bag_MenuSubYesNoSelectSeq( BAG_WORK * wk );
static int Bag_MenuSubCmpSeq( BAG_WORK * wk );
static int Bag_MenuSubRetSeq( BAG_WORK * wk );
static int Bag_MenuSet( BAG_WORK * wk );
static int Bag_MenuCnvSet( BAG_WORK * wk );
static int Bag_MenuCnvDel( BAG_WORK * wk );
static int Bag_MenuCnvErr( BAG_WORK *wk );
static int Bag_MenuItemMove( BAG_WORK * wk );
static int _pocket_search( BAG_WORK *wk, int pos );
static void AnimationFrameAdd( NNSG3dAnmObj *obj );

static int PokeItemSet_MainSeq( BAG_WORK * wk );
static int PokeItemSet_ErrorSeq( BAG_WORK * wk );
static int KinomiSel_MainSeq( BAG_WORK * wk );
static void BAG_CursorInit( BAG_WORK * wk );
static void BAG_CursorSave( BAG_WORK * wk );

static int BAG_ItemUse( BAG_WORK * wk );
static int Seq_BagItemUse( BAG_WORK * wk );
static int BAG_ItemUseWazaMachine( BAG_WORK * wk );
static BOOL BAG_ItemUseMsgNormal( BAG_WORK * wk, u16 item );
static STRBUF * BAG_SpraySet( BAG_WORK * wk, u16 item );
static STRBUF * BAG_GameboySet( BAG_WORK * wk, u16 item );
static void BAG_ItemSubListReset( BAG_WORK * wk );
static int BAG_ItemUseMsgNormalFunc( BAG_WORK * wk );

static void BAG_BackGroundPalChange( BAG_WORK *wk, int type, int no );
static void PageSet( BAG_WORK *wk, int page, int num, int target );
static void make_button_screen( GF_BGL_INI *bgl, int frm, int num );
static void make_insert_button_screen( GF_BGL_INI *bgl, int frm, int num, int target );

static int _get_page_button_num( BAG_WORK *wk );
static int _get_inpage_target( BAG_WORK *wk );
static void _item_explain_put( BAG_WORK *wk );

static int DecideFunc( BAG_WORK *wk, int pos, u8 *ret, int mode, int page, int keytouch );
static u32 CursorMenuMain( BAG_WORK *wk );
static void SelectMenuInit( BAG_WORK *wk, u8 *tbl );

static int CursorMove1Step( int pos );
static void item_change_page_refresh( BAG_WORK *wk, POCKET_DATA *p );
static u32 item_change_decide( BAG_WORK *wk, int pos );
static void select_menu_cancel( BAG_WORK *wk );
static int ItemNumMove( int num, int max, int move );
static void _set_keytouch_status( BAG_WORK *wk, int key_touch );

static void Init3D( BAG_WORK * wk );
static void Exit3D( BAG_WORK * wk );
static void Draw3DMain( BAG_WORK * wk );
static void Bag3DObjAnmChg( BAG_WORK * wk );
static void CameraModelMove( BAG_3D_WORK *wk3d, int sex );
static void CameraMoveStart( BAG_3D_WORK *wk, int next, int frame );
static void CameraMoveInit( BAG_3D_WORK *wk );
static void _cursor_pos_backup( BAG_WORK *wk, int pos );
static int _touch_no_move_check( BAG_WORK *wk, int touch );
static u16 _get_item_id( BAG_WORK *wk );

static int _next_pocket( BAG_WORK * wk, int pos, int mv );

static void _itemlist_update( BAG_WORK *wk, POCKET_DATA *p );

static void BackButtonOnOffChange( BAG_WORK * wk, BOOL flg );

static int Bag_MenuPlanterUse( BAG_WORK * wk );

static int ButtonPalAnmSet( BAG_WORK * wk, u8 id, u8 pal1, u8 pal2, int next );
static int ButtonAnmSet( BAG_WORK * wk, u8 id, u8 anm, int next );
static int ButtonAnmMain( BAG_WORK * wk );

static int MenuPageChange( BAG_WORK * wk );
static int SeqMenuCancel( BAG_WORK * wk );
static int SeqMenuSelect( BAG_WORK * wk );
static int ItemListPageChange( BAG_WORK * wk, s8 mv );
static int SaleMenuInit( BAG_WORK * wk );
static int SeqSaleNumEnter( BAG_WORK * wk );
static int SeqSaleNumCancel( BAG_WORK * wk );


#define ONE_PAGE_LIST_MAX ( 6 )   // 表示するアイテム数


//============================================================================================
//  グローバル変数
//============================================================================================

// プロセス定義データ
const PROC_DATA BagProcData = {
  BagProc_Init,
  BagProc_Main,
  BagProc_End,
  NO_OVERLAY_ID,
};

// どうぐの初期状態用のタッチ用データ
static const RECT_HIT_TBL TouchButtonNormalTbl[]={
  { 0, 31, 0,     31,     },  // ポケット選択８つ
  { 0, 31, 0+ 32, 31+ 32, },
  { 0, 31, 0+ 64, 31+ 64, },
  { 0, 31, 0+ 96, 31+ 96, },
  { 0, 31, 0+128, 31+128, },
  { 0, 31, 0+160, 31+160, },
  { 0, 31, 0+192, 31+192, },
  { 0, 31, 0+224, 31+224, },

  {  32,  73,   0, 127,},   // どうぐ６つ
  {  32,  73, 128, 255,},
  {  74, 117,   0, 127,},
  {  74, 117, 128, 255,},
  { 118, 153,   0, 127,},
  { 118, 153, 128, 255,},

  { 168, 191,   0,  39,},   // 左ページ
  { 168, 191,  40,  79,},   // 右ページ
  { 168, 191, 192, 255,},   // やめる

  {TP_HIT_END,0,0,0},   // 終了データ

};

// どうぐ選択後のタッチデータ
static const RECT_HIT_TBL TouchButtonSelectTbl[]={
  { 128, 159,   0,  93,},   // 選択肢0
  { 128, 159,  96, 191,},   // 選択肢1
  { 160, 191,   0,  93,},   // 選択肢2
  { 160, 191,  96, 191,},   // 選択肢3
  { 168, 191, 192, 255,},   // やめる

  {TP_HIT_END,0,0,0},   // 終了データ
};

// どうぐ移動時のタッチデータ
static const RECT_HIT_TBL TouchButtonChangeTbl[]={
  {  32,  73,   0, 127,},   // どうぐ６つ
  {  32,  73, 128, 255,},
  {  74, 117,   0, 127,},
  {  74, 117, 128, 255,},
  { 118, 153,   0, 127,},
  { 118, 153, 128, 255,},

  { 168, 191,   0,  39,},   // 左ページ
  { 168, 191,  40,  79,},   // 右ページ
  { 168, 191, 192, 255,},   // やめる

  {TP_HIT_END,0,0,0},   // 終了データ

};

// 数値入力時
static const RECT_HIT_TBL TouchButtonNumInputTbl[]={

  {  88, 111, 120, 151, },  // 100の桁アップ
  {  88, 111, 152, 183, },  // 10の桁アップ
  {  88, 111, 184, 215, },  // 1の桁アップ
  { 136, 159, 120, 151, },  // 100の桁ダウン
  { 136, 159, 152, 183, },  // 10の桁ダウン
  { 136, 159, 184, 215, },    // 1の桁ダウン


  { 168, 191, 128, 183,},   // すてる
  { 168, 191, 192, 255,},   // やめる

  {TP_HIT_END,0,0,0},   // 終了データ
};


// 数値入力時
static const RECT_HIT_TBL TouchButtonSaleNumInputTbl[]={

  {  88, 111, 120, 151, },  // 10の桁アップ
  {  88, 111, 152, 183, },  // 1の桁アップ
  { 136, 159, 120, 151, },  // 10の桁ダウン
  { 136, 159, 152, 183, },  // 1の桁ダウン


  { 168, 191, 128, 183,},   // うる
  { 168, 191, 192, 255,},   // やめる

  {TP_HIT_END,0,0,0},   // 終了データ
};

// 各ポケットの最大数
static const u8 PocketMax[] = {
  BAG_NORMAL_ITEM_MAX,  // 道具ポケット最大数
  BAG_DRUG_ITEM_MAX,    // 薬ポケット最大数
  BAG_BALL_ITEM_MAX,    // モンスターボールポケット最大数
  BAG_WAZA_ITEM_MAX,    // 技マシンポケット最大数
  BAG_NUTS_ITEM_MAX,    // 木の実ポケット最大数
  BAG_SEAL_ITEM_MAX,    // シールポケット最大数
  BAG_BATTLE_ITEM_MAX,  // 戦闘用アイテムポケット最大数
  BAG_EVENT_ITEM_MAX,   // 大切な物ポケット最大数
};

// メニューパラメータテーブル
int (*MenuFuncTbl[])( BAG_WORK *wk)={
  Bag_MenuUse,    // つかう
  Bag_MenuUse,    // おりる
  Bag_MenuUse,    // みる
  Bag_MenuUse,    // うめる
  Bag_MenuUse,    // ひらく
  Bag_MenuSub,    // すてる
  Bag_MenuCnvSet,   // とうろく
  Bag_MenuCnvDel,   // かいじょ
  Bag_MenuSet,    // もたせる
  Bag_MenuTag,    // タグをみる
  Bag_MenuKettei,   // けってい
  NULL,       // やめる
  Bag_MenuItemMove, // いどう
  NULL,       // うる
  Bag_MenuPlanterUse, // つかう（木の実プランター用）
  Bag_MenuUse,    // とめる
};

// 下画面の決定ボタンのタッチ座標テーブル
static const RECT_HIT_TBL EnterButtonRect[] =
{
  { 56, 103, 104, 151 },
  { RECT_HIT_END, 0, 0, 0 }
};


//============================================================================================
//  プロセス関数
//============================================================================================

//--------------------------------------------------------------------------------------------
/**
 * プロセス関数：初期化
 *
 * @param proc  プロセスデータ
 * @param seq   シーケンス
 *
 * @return  処理状況
 */
//--------------------------------------------------------------------------------------------
PROC_RESULT BagProc_Init( PROC * proc, int * seq )
{
  BAG_WORK * wk;

  sys_VBlankFuncChange( NULL, NULL ); // VBlankセット
  sys_HBlankIntrStop();       // HBlank停止

  GF_Disp_GX_VisibleControlInit();
  GF_Disp_GXS_VisibleControlInit();
  GX_SetVisiblePlane( 0 );
  GXS_SetVisiblePlane( 0 );

  G2_BlendNone();
  G2S_BlendNone();

  sys_CreateHeap( HEAPID_BASE_APP, HEAPID_BAG, 0x42000 );

  wk = PROC_AllocWork( proc, sizeof(BAG_WORK), HEAPID_BAG );
  memset( wk, 0, sizeof(BAG_WORK) );
  wk->dat = PROC_GetParentWork( proc );

  BAG_SaveDataGet( wk );

  wk->bgl = GF_BGL_BglIniAlloc( HEAPID_BAG );

  wk->sex  = MyStatus_GetMySex( wk->myst );

  WIPE_SYS_Start(
    WIPE_PATTERN_FSAM, WIPE_TYPE_SHUTTERIN_DOWN, WIPE_TYPE_SHUTTERIN_DOWN,
    WIPE_FADE_BLACK, WIPE_DEF_DIV, WIPE_DEF_SYNC, HEAPID_BAG );

  sys_KeyRepeatSpeedSet( 3, 8 );

  BAG_CursorInit( wk );       // カーソル位置、ポケット初期設定

  MsgManCreate( wk );         // メッセージマネージャー作成
  ItemListStrAlloc( wk );       // どうぐ名文字列バッファ作成（１６５個ｘ36バイト)

  PocketDataInit( wk );       // ポケット設定
  PocketIconXmake( wk );        // アイコンの座標取得

  BagVramBankSet();         // VRAM設定
  BagBgSet( wk->bgl );        // BG設定
  BagBgGraphicSet( wk );        // BGグラフィックセット

  InitTPSystem();           // タッチパネルシステム初期化
  InitTPNoBuff(4);

  BagBmpWinSet( wk );         // BMPウィンドウ設定

  // メッセージをタッチパネルでも送れるように設定
  MsgPrintTouchPanelFlagSet( MSG_TP_ON );

  Bag_PocketNameMake( wk );     // ポケット名取得
  Bag_PocketNameScreenPut( wk );    // ポケット名をスクリーンに反映

  Bag_MenuStrGet( wk );       // メニュー項目取得
  Bag_NumStrGet( wk );        // 個数表示文字列取得

#ifdef FIX_BAG_DATA
  {
    int i;
    // 道具MAX番号を超えているデータを削除する
    for(i=0;i<165;i++){
      if(wk->dat->p_data[0].item[i].id>ITEM_DATA_MAX){
        wk->dat->p_data[0].item[i].id=0;
        wk->dat->p_data[0].item[i].no=0;
      }
    }
    // 途中にデータ番号0が存在していて個数が１以上になっている場合は0クリアする
    for(i=0;i<165;i++){
      if(wk->dat->p_data[0].item[i].id==0 && wk->dat->p_data[0].item[i].no!=0){
        wk->dat->p_data[0].item[i].no=0;
      }
    }

    MyItem_SortSpace( wk->dat->p_data[0].item, 165 );
  }
#endif

  ItemListDataMake( wk );       // アイテムリスト作成

  BagBmp_CancelPrint( wk, 0 );    // 「やめる」表示


  ItemListParamReset(
    &wk->dat->p_data[wk->dat->p_now].scr,
    &wk->dat->p_data[wk->dat->p_now].cur,
    wk->dat->p_data[wk->dat->p_now].max );

  ItemListCurPosReset(
    &wk->dat->p_data[wk->dat->p_now].scr,
    &wk->dat->p_data[wk->dat->p_now].cur,
    wk->dat->p_data[wk->dat->p_now].max, ONE_PAGE_LIST_MAX );

  BagCellActorInit( wk );       // セルアクター初期化

  // ページ設定
  PageSet( wk, BAG_PAGE_NORMAL, _get_page_button_num(wk), 0 );
  BagBmp_ItemNamePrint( wk, wk->dat->p_data[wk->dat->p_now].scr, -1, ITEMPRINT_NORMAL );
  BgObj_PocketPalSet( wk, wk->dat->p_now );
  BAG_BackGroundPalChange( wk, 1, wk->dat->p_now );
  BagBmp_PageNoPrint( wk, wk->dat->p_data[wk->dat->p_now].max,
              wk->dat->p_data[wk->dat->p_now].scr, 0 );
  BagObj_ItemIconSet( wk, &wk->dat->p_data[wk->dat->p_now], _get_page_button_num(wk), 1 );

  // 昔のカーソル位置に移動させる
  wk->cursor_pos = wk->dat->p_data[wk->dat->p_now].cur+8;
  BgObj_CursorPosAppearSet( wk, wk->cursor_pos );
  {
    int i;
    for(i=0;i<8;i++){
      POCKET_DATA *p= &wk->dat->p_data[i];
      OS_Printf("page:%d, cur=%d, scr=%d\n", i, p->cur, p->scr);
    }
  }
  _item_explain_put( wk );  // 説明表示

  if( wk->dat->mode == BAG_MODE_MIX || wk->dat->mode == BAG_MODE_MIX_SIO ){
    // ポフィンのかず表示用
    BagBmp_PorutoWinPut( wk );
  }

  Init3D( wk ); // 3D初期化

  sys_VBlankFuncChange( BagVBlank, wk );    // VBlankセット

  Snd_DataSetByScene( SND_SCENE_SUB_BAG, 0, 0 );  // サウンドデータロード(バッグ)(BGM引継ぎ)

  // 通信無線アイコン表示(通信中でなければ自動的に表示しません）
  WirelessIconEasyUnion();

  GX_SetDispSelect(GX_DISP_SELECT_MAIN_SUB);
  GF_BGL_VisibleSet( GF_BGL_FRAME0_S, VISIBLE_ON );

  OS_Printf("ADD_SUB_CGX  =%08x\n",ADD_SUB_CGX );

  return PROC_RES_FINISH;
}

//--------------------------------------------------------------------------------------------
/**
 * プロセス関数：メイン
 *
 * @param proc  プロセスデータ
 * @param seq   シーケンス
 *
 * @return  処理状況
 */
//--------------------------------------------------------------------------------------------
PROC_RESULT BagProc_Main( PROC * proc, int * seq )
{
  BAG_WORK * wk  = PROC_GetWork( proc );


  switch( *seq ){
  case SEQ_IN:
    // フェード待ち
    if( WIPE_SYS_EndCheck() == TRUE ){
      // モードで分岐
      switch(wk->dat->mode){
      case BAG_MODE_ITEMSALE:
        *seq = SEQ_SALE_MAIN;
        break;
      case BAG_MODE_ITEMSET:
        *seq = SEQ_ITEMSET_MAIN;
        break;
      case BAG_MODE_KINOMI:
        *seq = SEQ_KINOMISEL_MAIN;
        break;
      default:
        *seq = SEQ_MAIN;
      }

      OS_Printf( "bag heap remain = %d\n", sys_GetHeapFreeSize(HEAPID_BAG));
    }
    break;

  // メイン
  case SEQ_MAIN:
    *seq = MainSeqFunc( wk );
    break;

  // ページ切り替え
  case SEQ_PAGE:
    if( PocketChange( wk ) == TRUE ){
      if( wk->dat->mode == BAG_MODE_ITEMSALE ){
        *seq = SEQ_SALE_MAIN;
      }else if( wk->dat->mode == BAG_MODE_ITEMSET ){
        *seq = SEQ_ITEMSET_MAIN;
      }else if( wk->dat->mode == BAG_MODE_KINOMI ){
        *seq = SEQ_KINOMISEL_MAIN;
      }else{
        *seq = SEQ_MAIN;
      }
    }
    break;

  // 入れ替えシーケンス
  case SEQ_IREKAE:
    *seq = ItemChangeMain( wk );
    break;

  // メニュー
  case SEQ_MENU:
    *seq = MenuControl( wk );
    break;

  case SEQ_ITEM_SUB_MAIN:   // メニュー「すてる」個数選択
    *seq = Bag_MenuSubMain( wk );
    break;

  case SEQ_ITEM_SUB_ENTER:
    *seq = Bag_MenuSubNumEnter( wk );
    break;

  case SEQ_ITEM_SUB_CANCEL:
    *seq = Bag_MenuSubNumCancel( wk );
    break;

  case SEQ_ITEM_SUB_YN_INIT:  // メニュー「すてる」はい・いいえ初期化
    *seq = Bag_MenuSubYesNoInitSeq( wk );
    break;
  case SEQ_ITEM_SUB_YN_SEL: // メニュー「すてる」はい・いいえ
    *seq = Bag_MenuSubYesNoSelectSeq( wk );
    break;
  case SEQ_ITEM_SUB_CMP:    // メニュー「すてる」完了
    *seq = Bag_MenuSubCmpSeq( wk );
    break;
  case SEQ_ITEM_SUB_RET:    // メニュー「すてる」メッセージ終了待ち＆ボタン待ち -> メインへ
    *seq = Bag_MenuSubRetSeq( wk );
    break;

  case SEQ_ITEM_ERR_WAIT:   // アイテム使用エラー
    *seq = ItemErrWaitSeq( wk );
    break;

  case SEQ_BAG_ITEMUSE: // バッグ内アイテム使用
    *seq = Seq_BagItemUse( wk );
    break;

  case SEQ_ITEMSET_MAIN:    // 「もたせる」メイン
    *seq = PokeItemSet_MainSeq( wk );
    break;
  case SEQ_ITEMSET_ERR:   // 「もたせる」エラー
    *seq = PokeItemSet_ErrorSeq( wk );
    break;

  case SEQ_SALE_MAIN:   // 「売る」モードアイテム選択
    *seq = SaleMainSeq( wk );
    break;
  case SEQ_SALE_NUM_INIT: // 「売る」モード個数選択初期化
    *seq = SaleNumInitSeq( wk );
    break;
  case SEQ_SALE_NUM_SEL:  // 「売る」モード個数選択
    *seq = SaleNumSelSeq( wk );
    break;
  case SEQ_SALE_NUM_ENTER:
    *seq = SeqSaleNumEnter( wk );
    break;
  case SEQ_SALE_NUM_CANCEL:
    *seq = SeqSaleNumCancel( wk );
    break;
  case SEQ_SALE_YN_INIT:  // 「売る」はい・いいえ初期化
    *seq = SaleYesNoInitSeq( wk );
    break;
  case SEQ_SALE_YN_SEL: // 「売る」はい・いいえ
    *seq = SaleYesNoSelectSeq( wk );
    break;
  case SEQ_SALE_CMP:    // 「売る」完了
    *seq = SaleCmpSeq( wk );
    break;
  case SEQ_SALE_RET:    // 「売る」メッセージ終了待ち＆ボタン待ち -> メインへ
    *seq = SaleRetSeq( wk );
    break;

  case SEQ_KINOMISEL_MAIN:  // 木の実関連選択処理
    *seq = KinomiSel_MainSeq( wk );
    break;

  case SEQ_ITEM_REGIST_ERR: // どうぐの登録に失敗
    *seq = Bag_MenuCnvErr( wk );
    break;

  case SEQ_MENU_INIT:
    *seq = MenuPageChange( wk );
    break;

  case SEQ_MENU_CANCEL:
    *seq = SeqMenuCancel( wk );
    break;

  case SEQ_MENU_SELECT:
    *seq = SeqMenuSelect( wk );
    break;

  case SEQ_LIST_ADD:
    *seq = ItemListPageChange( wk, 1 );
    break;

  case SEQ_LIST_SUB:
    *seq = ItemListPageChange( wk, -1 );
    break;

  case SEQ_IREKAE_CANCEL:
    *seq = ItemChangeEnd( wk );
    break;

  case SEQ_IREKAE_COMP:
    *seq = ItemChangeComp( wk );
    break;

  case SEQ_SALE_MENU_INIT:
    *seq = SaleMenuInit( wk );
    break;

  case SEQ_BUTTON_ANM:
    *seq = ButtonAnmMain( wk );
    break;

  case SEQ_OUT_SET:
    APP_WipeStart( APP_WIPE_OUT, HEAPID_BAG );
    *seq = SEQ_OUT;
    break;

  case SEQ_OUT:
    if( WIPE_SYS_EndCheck() == TRUE ){
      return PROC_RES_FINISH;
    }
    break;
  }

  Bag_ObjAnmMain( wk );
  CATS_Draw( wk->crp );
  Draw3DMain( wk );

  return PROC_RES_CONTINUE;
}

//--------------------------------------------------------------------------------------------
/**
 * プロセス関数：終了
 *
 * @param proc  プロセスデータ
 * @param seq   シーケンス
 *
 * @return  処理状況
 */
//--------------------------------------------------------------------------------------------
PROC_RESULT BagProc_End( PROC * proc, int * seq )
{
  BAG_WORK * wk  = PROC_GetWork( proc );

  Exit3D( wk );   // 3D削除

  BAGOBJ_ClactFree( wk );

  sys_FreeMemoryEz( wk->bgPalData[0] );
  sys_FreeMemoryEz( wk->bgPalData[1] );

  ItemListExit( wk );       // アイテムリスト削除
  BAG_CursorSave( wk );
  BagBmpWinExit( wk );      // BMPウィンドウ開放
  BagBgExit( wk->bgl );     // BGL削除
  StopTP();           // タッチパネル終了
  DellVramTransferManager();

  Bag_MenuStrRelease( wk );
  Bag_PocketNameRelease( wk );
  Bag_NumStrRelease( wk );

  ItemListStrFree( wk );

  STRBUF_Delete( wk->expb );

  MSGMAN_Delete( wk->waza_man );
  MSGMAN_Delete( wk->item_man );
  MSGMAN_Delete( wk->msg_man );
  NUMFONT_Delete( wk->num_font );
  WORDSET_Delete( wk->wset );

  ArchiveDataHandleClose( wk->gra_h );

  PROC_FreeWork( proc );        // ワーク開放

  // 追加SE領域を開放する
  Snd_SubSceneClear( );

  sys_VBlankFuncChange( NULL, NULL );   // VBlankセット

  sys_DeleteHeap( HEAPID_BAG );

  return PROC_RES_FINISH;
}


//============================================================================================
//  セーブデータ操作
//============================================================================================

//--------------------------------------------------------------------------------------------
/**
 * セーブデータから必要なデータを取り出す
 *
 * @param wk    ワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void BAG_SaveDataGet( BAG_WORK * wk )
{
  wk->myitem = SaveData_GetMyItem( wk->dat->sv );
  wk->myst   = SaveData_GetMyStatus( wk->dat->sv );
  wk->cfg    = SaveData_GetConfig( wk->dat->sv );
}

//--------------------------------------------------------------------------------------------
/**
 * エンカウントセーブデータのポインタ取得
 *
 * @param wk    ワーク
 *
 * @return  エンカウントセーブデータのポインタ
 */
//--------------------------------------------------------------------------------------------
static ENC_SV_PTR BAG_EncountSaveGet( BAG_WORK * wk )
{
  return EncDataSave_GetSaveDataPtr( wk->dat->sv );
}

//--------------------------------------------------------------------------------------------
/**
 * セーブデータにスプレーの効果を入れる
 *
 * @param wk    ワーク
 * @param prm   スプレーの効果
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void BAG_SaveDataSpraySet( BAG_WORK * wk, u8 prm )
{
  u8 * swk;

  swk  = EncDataSave_GetSprayCnt( BAG_EncountSaveGet(wk) );
  *swk = prm;
}

//--------------------------------------------------------------------------------------------
/**
 * セーブデータにビードロの効果を入れる
 *
 * @param wk    ワーク
 * @param type  ビードロのタイプ
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void BAG_SaveDataVidroSet( BAG_WORK * wk, u8 type )
{
  EncDataSave_SetVidro( BAG_EncountSaveGet(wk), type );
}


//============================================================================================
//  設定
//============================================================================================

//--------------------------------------------------------------------------------------------
/**
 * VBlank関数
 *
 * @param work  バッグ画面ワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void BagVBlank( void * work )
{
  BAG_WORK * wk = work;

  GF_BGL_VBlankFunc( wk->bgl );

  // セルアクター
  DoVramTransferManager();  // Vram転送マネージャー実行
  CATS_RenderOamTrans();

  OS_SetIrqCheckFlag( OS_IE_V_BLANK );
}

//--------------------------------------------------------------------------------------------
/**
 * VRAM設定
 *
 * @param none
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void BagVramBankSet(void)
{
  GF_BGL_DISPVRAM tbl = {
    GX_VRAM_BG_64_E,        // メイン2DエンジンのBG
    GX_VRAM_BGEXTPLTT_NONE,     // メイン2DエンジンのBG拡張パレット

    GX_VRAM_SUB_BG_128_C,     // サブ2DエンジンのBG
    GX_VRAM_SUB_BGEXTPLTT_NONE,   // サブ2DエンジンのBG拡張パレット

    GX_VRAM_OBJ_128_B,        // メイン2DエンジンのOBJ
    GX_VRAM_OBJEXTPLTT_NONE,    // メイン2DエンジンのOBJ拡張パレット

    GX_VRAM_SUB_OBJ_16_I,     // サブ2DエンジンのOBJ
    GX_VRAM_SUB_OBJEXTPLTT_NONE,  // サブ2DエンジンのOBJ拡張パレット

    GX_VRAM_TEX_0_A,        // テクスチャイメージスロット
    GX_VRAM_TEXPLTT_01_FG     // テクスチャパレットスロット
  };
  GF_Disp_SetBank( &tbl );
}

//--------------------------------------------------------------------------------------------
/**
 * BG設定
 *
 * @param ini   BGLデータ
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void BagBgSet( GF_BGL_INI * ini )
{
  { // BG SYSTEM
    GF_BGL_SYS_HEADER BGsys_data = {
      GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BGMODE_0, GX_BG0_AS_3D,
    };
    GF_BGL_InitBG( &BGsys_data );
  }

  // メイン面初期化
  {
    static const GF_BGL_BGCNT_HEADER TextBgCntDatM[] = {
      // MENU & INFO (BMP)
      {
        0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
        GX_BG_SCRBASE_0xf800, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01,
        0, 0, 0, FALSE
      },
      // FRAME (CHAR)
      {
        0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
        GX_BG_SCRBASE_0xf000, GX_BG_CHARBASE_0x08000, GX_BG_EXTPLTT_01,
        1, 0, 0, FALSE
      },
      // ITEM LIST (BMP)
      {
        0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
        GX_BG_SCRBASE_0xe800, GX_BG_CHARBASE_0x08000, GX_BG_EXTPLTT_01,
        2, 0, 0, FALSE
      },
    };
    GF_BGL_BGControlSet( ini, GF_BGL_FRAME1_M, &TextBgCntDatM[0], GF_BGL_MODE_TEXT );
    GF_BGL_BGControlSet( ini, GF_BGL_FRAME2_M, &TextBgCntDatM[1], GF_BGL_MODE_TEXT );
    GF_BGL_BGControlSet( ini, GF_BGL_FRAME3_M, &TextBgCntDatM[2], GF_BGL_MODE_TEXT );

    GF_BGL_ScrClear( ini, GF_BGL_FRAME1_M );
    GF_BGL_ScrClear( ini, GF_BGL_FRAME3_M );

    GF_BGL_ClearCharSet( GF_BGL_FRAME1_M, 32, 0, HEAPID_BAG );
  }


  // サブ面初期化
  {
    static const GF_BGL_BGCNT_HEADER TextBgCntDatS[] = {
      // FONT (CHAR)
      {
        0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
        GX_BG_SCRBASE_0xf800, GX_BG_CHARBASE_0x10000, GX_BG_EXTPLTT_01,
        0, 0, 0, FALSE
      },
      // BAG BUTTON (CHAR)
      {
        0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
        GX_BG_SCRBASE_0xf000, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01,
        2, 0, 0, FALSE
      },
      // BACK GROUND (CHAR)
      {
        0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
        GX_BG_SCRBASE_0xe800, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01,
        3, 0, 0, FALSE
      },
      // YES/NO (CHAR)
      {
        0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
        GX_BG_SCRBASE_0xe000, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01,
        0, 0, 0, FALSE
      },
    };

    GF_BGL_BGControlSet( ini, GF_BGL_FRAME0_S, &TextBgCntDatS[0], GF_BGL_MODE_TEXT );
    GF_BGL_BGControlSet( ini, GF_BGL_FRAME1_S, &TextBgCntDatS[1], GF_BGL_MODE_TEXT );
    GF_BGL_BGControlSet( ini, GF_BGL_FRAME2_S, &TextBgCntDatS[2], GF_BGL_MODE_TEXT );
    GF_BGL_BGControlSet( ini, GF_BGL_FRAME3_S, &TextBgCntDatS[3], GF_BGL_MODE_TEXT );

    GF_BGL_ScrClear( ini, GF_BGL_FRAME0_S );
    GF_BGL_ScrClear( ini, GF_BGL_FRAME3_S );

    GF_BGL_ClearCharSet( GF_BGL_FRAME0_S, 32, 0, HEAPID_BAG );
    GF_BGL_ClearCharSet( GF_BGL_FRAME3_S, 32, 0, HEAPID_BAG );

  }
  // BG2面に半透明設定を行う（実際のαは3Dが反映されるので入れる必要なし）
  G2_SetBlendAlpha(    0, GX_BLEND_PLANEMASK_BG3, 0,0);
}

//--------------------------------------------------------------------------------------------
/**
 * BG解放
 *
 * @param ini   BGLデータ
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void BagBgExit( GF_BGL_INI * ini )
{
  GF_Disp_GX_VisibleControl(
    GX_PLANEMASK_BG0 | GX_PLANEMASK_BG1 | GX_PLANEMASK_BG2 |
    GX_PLANEMASK_BG3 | GX_PLANEMASK_OBJ, VISIBLE_OFF );
  GF_Disp_GXS_VisibleControl(
    GX_PLANEMASK_BG0 | GX_PLANEMASK_BG1 | GX_PLANEMASK_BG3 | GX_PLANEMASK_OBJ, VISIBLE_OFF );

  GF_BGL_BGControlExit( ini, GF_BGL_FRAME3_S );
  GF_BGL_BGControlExit( ini, GF_BGL_FRAME2_S );
  GF_BGL_BGControlExit( ini, GF_BGL_FRAME1_S );
  GF_BGL_BGControlExit( ini, GF_BGL_FRAME0_S );

  GF_BGL_BGControlExit( ini, GF_BGL_FRAME3_M );
  GF_BGL_BGControlExit( ini, GF_BGL_FRAME2_M );
  GF_BGL_BGControlExit( ini, GF_BGL_FRAME1_M );
//  GF_BGL_BGControlExit( ini, GF_BGL_FRAME0_M );

  sys_FreeMemory( HEAPID_BAG, ini );
}

//--------------------------------------------------------------------------------------------
/**
 * グラフィックデータセット
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void BagBgGraphicSet( BAG_WORK * wk )
{
  wk->gra_h = ArchiveDataHandleOpen( ARC_BAG_GRA, HEAPID_BAG );

  // ----------- メイン画面 -------------------

  // どうぐ説明の背景（ここからは消す）
  ArcUtil_BgCharSet(
    ARC_BAG_GRA, NARC_bag_gra_bag_bg_NCGR, wk->bgl, GF_BGL_FRAME2_M, 0, 0, 0, HEAPID_BAG );
  ArcUtil_ScrnSet(
    ARC_BAG_GRA, NARC_bag_gra_bag_bg1b_nscr, wk->bgl, GF_BGL_FRAME2_M, 0, 0, 0, HEAPID_BAG );

  // メイン画面BG3は男女で背景を読み替える
  if( wk->sex == 0 ){
    ArcUtil_ScrnSet(
      ARC_BAG_GRA, NARC_bag_gra_itemBG_boy_u_nscr, wk->bgl, GF_BGL_FRAME3_M, 0, 0, 0, HEAPID_BAG );
  }else{
    ArcUtil_ScrnSet(
      ARC_BAG_GRA, NARC_bag_gra_itemBG_girl_u_nscr, wk->bgl, GF_BGL_FRAME3_M, 0, 0, 0, HEAPID_BAG );
  }
  ArcUtil_PalSet(
    ARC_BAG_GRA, NARC_bag_gra_bag_bg_NCLR, PALTYPE_MAIN_BG, 0, 0, HEAPID_BAG );

  // アイコンパレット
  ArcUtil_PalSet(
    ARC_BAG_GRA, NARC_bag_gra_bag_pocketlist_NCLR, PALTYPE_MAIN_BG, 16*13*2, 32, HEAPID_BAG );

  TalkFontPaletteLoad( PALTYPE_MAIN_BG, TALK_FONT_PAL * 32, HEAPID_BAG );

  // メニューウィンドウセット
  MenuWinGraphicSet( wk->bgl, GF_BGL_FRAME1_M, MENU_WIN_CGX_NUM, MENU_WIN_PAL, 0, HEAPID_BAG );
  // 会話ウィンドウセット
  TalkWinGraphicSet(
    wk->bgl, GF_BGL_FRAME1_M, TALK_WIN_CGX_NUM,
    TALKWIN_PAL, CONFIG_GetWindowType(wk->cfg), HEAPID_BAG );


  // ------------ サブ画面 ------------------
  // パレット
  ArcUtil_PalSet(     ARC_BAG_GRA, NARC_bag_gra_itemBG01_d_nclr, PALTYPE_SUB_BG, 0, 0, HEAPID_BAG );

  // 会話フォントパレット
  TalkFontPaletteLoad( PALTYPE_SUB_BG, TALK_FONT_PAL * 32, HEAPID_BAG );

  // キャラ
  ArcUtil_BgCharSet(  ARC_BAG_GRA, NARC_bag_gra_itemBG_d_ncgr, wk->bgl,
            GF_BGL_FRAME2_S, 0, 0, 0, HEAPID_BAG );

  // 背景のスクリーンセットはBAG_PageSetで行う


  // あとから背景切り替えように使うパレットデータを読み込む
  wk->bgPalData[0] = ArcUtil_PalDataGet( ARC_BAG_GRA, NARC_bag_gra_itemBG02_d_nclr, &wk->bgPalPtr[0], HEAPID_BAG );
  wk->bgPalData[1] = ArcUtil_PalDataGet( ARC_BAG_GRA, NARC_bag_gra_itemBG03_d_nclr, &wk->bgPalPtr[1], HEAPID_BAG );

  // 一部のアイコンBG面に表示するアイコンに使用するパレットの転送
  ArcUtil_PalSet(
    ARC_BAG_GRA, NARC_bag_gra_bag_bg_NCLR, PALTYPE_SUB_BG, 8*32, 4*32, HEAPID_BAG );

  // 会話ウィンドウセット
  TalkWinGraphicSet(
    wk->bgl, GF_BGL_FRAME0_S, TALK_SUB_WIN_CGX_NUM,
    TALKWIN_PAL, CONFIG_GetWindowType(wk->cfg), HEAPID_BAG );
}

//--------------------------------------------------------------------------------------------
/**
 * @brief 上画面説明ウィンドウ読み込み
 *
 * @param wk    バッグ画面のワーク
 * @param flg   TRUE = 通常, FALSE = 技マシン用
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
void BAGMAIN_InfoWinLoad( BAG_WORK * wk, BOOL flg )
{
  if( flg == TRUE ){
    ArcUtil_ScrnSet(
      ARC_BAG_GRA, NARC_bag_gra_bag_bg1b_nscr,
      wk->bgl, GF_BGL_FRAME2_M, 0, 0, 0, HEAPID_BAG );
  }else{
    ArcUtil_ScrnSet(
      ARC_BAG_GRA, NARC_bag_gra_bag_bg1_NSCR,
      wk->bgl, GF_BGL_FRAME2_M, 0, 0, 0, HEAPID_BAG );
  }
}


//--------------------------------------------------------------------------------------------
/**
 * メッセージ関連作成
 *
 * @param wk    バッグ画面ワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void MsgManCreate( BAG_WORK * wk )
{
  // メッセージマネージャ作成
  wk->msg_man = MSGMAN_Create( MSGMAN_TYPE_NORMAL, ARC_MSG, NARC_msg_bag_dat, HEAPID_BAG );
  // 8x8フォント作成
  wk->num_font = NUMFONT_Create( FBMP_COL_BLACK, FBMP_COL_BLK_SDW, FBMP_COL_NULL, HEAPID_BAG );

  wk->wset = WORDSET_Create( HEAPID_BAG );

  wk->item_man = MSGMAN_Create( MSGMAN_TYPE_NORMAL, ARC_MSG, NARC_msg_itemname_dat, HEAPID_BAG );
  wk->waza_man = MSGMAN_Create( MSGMAN_TYPE_NORMAL, ARC_MSG, NARC_msg_wazaname_dat, HEAPID_BAG );

  // メッセージ展開用バッファ
  wk->expb = STRBUF_Create( BAG_TMPMSG_SIZ, HEAPID_BAG );
}

//--------------------------------------------------------------------------------------------
/**
 * ポケット数取得
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void PocketDataInit( BAG_WORK * wk )
{
  u8  i;

  wk->p_max = 0;
  for( i=0; i<BAG_POKE_MAX; i++ ){
    if( wk->dat->p_data[i].item != 0 ){
      wk->p_max++;
    }
  }
}

//--------------------------------------------------------------------------------------------
/**
 * @brief 現在のポケットの指定位置のアイテムを取得
 *
 * @param wk    バッグ画面のワーク
 * @param pos   位置
 * @param id    取得ID
 *
 * @return  指定位置のアイテム
 *
 * @li  id = POS_GET_ID : アイテム番号
 * @li  id = POS_GET_NUM : 所持数
 */
//--------------------------------------------------------------------------------------------
u16 Bag_PosItemGet( BAG_WORK * wk, u16 pos, u16 id )
{
  POCKET_DATA * pocket = &wk->dat->p_data[wk->dat->p_now];

  if( id == POS_GET_ID ){
    return pocket->item[pos].id;
  }
  return pocket->item[pos].no;
}

//--------------------------------------------------------------------------------------------
/**
 * アイテム名取得
 *
 * @param man     メッセージマネージャ
 * @param buf     格納場所
 * @param item    アイテム番号
 * @param heap_id   ヒープＩＤ
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void BAG_GetItemName( MSGDATA_MANAGER * man, STRBUF * buf, u16 item, u32 heap_id )
{
  MSGMAN_GetString( man, item, buf );
}

//--------------------------------------------------------------------------------------------
/**
 * 技マシンの技名取得
 *
 * @param man     メッセージマネージャ
 * @param buf     格納場所
 * @param item    アイテム番号
 * @param heap_id   ヒープＩＤ
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void BAG_GetItemWazaName( MSGDATA_MANAGER * man, STRBUF * buf, u16 item, u32 heap_id )
{
  MSGMAN_GetString( man, GetWazaNoItem(item), buf );
}

//--------------------------------------------------------------------------------------------
/**
 * カーソル初期化
 *
 * @param wk    バッグ画面ワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void BAG_CursorInit( BAG_WORK * wk )
{
  POCKET_DATA * pocket;
  u16 i, pid;

  wk->dat->p_now = 0;

  pocket = wk->dat->p_data;

  if( wk->dat->bag_cursor == NULL ){
    for( i=0; i<BAG_POKE_MAX; i++ ){
//      if( pocket[i].item == NULL ){ break; }
      if( pocket[i].item == NULL ){ continue; }
      pocket[i].cur = 0;
      pocket[i].scr = 0;
    }
    for( i=0; i<BAG_POKE_MAX; i++ ){
      if( pocket[i].item != NULL ){
        wk->dat->p_now = i;
        break;
      }
    }
    return;
  }

  for( i=0; i<BAG_POKE_MAX; i++ ){
    u8  pos, scr;
//    if( pocket[i].item == NULL ){ break; }
    if( pocket[i].item == NULL ){ continue; }
    MyItem_FieldBagCursorGet( wk->dat->bag_cursor, pocket[i].type, &pos, &scr );
//    if( pos == 0 ){ pos = 1; }
    pocket[i].cur = pos;
    pocket[i].scr = scr;
  }

  pid = MyItem_FieldBagPocketGet( wk->dat->bag_cursor );
  if( pocket[pid].item == NULL ){
    for( i=0; i<BAG_POKE_MAX; i++ ){
      if( pocket[i].item != NULL ){
        pid = i;
        break;
      }
    }
  }

  for( i=0; i<BAG_POKE_MAX; i++ ){
//    if( pocket[i].item == NULL ){ break; }
    if( pocket[i].item == NULL ){ continue; }
    if( pocket[i].type == pid ){
      wk->dat->p_now = (u8)i;
      break;
    }
  }
}

//--------------------------------------------------------------------------------------------
/**
 * カーソル位置記憶
 *
 * @param wk    バッグ画面ワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void BAG_CursorSave( BAG_WORK * wk )
{
  POCKET_DATA * pocket;
  u32 i;

  if( wk->dat->bag_cursor == NULL ){ return; }

  pocket = wk->dat->p_data;

  for( i=0; i<BAG_POKE_MAX; i++ ){
    if( pocket[i].item == NULL ){ continue; }

    // ポケット毎のカーソル位置を保存
    MyItem_FieldBagCursorSet(
      wk->dat->bag_cursor, pocket[i].type, (u8)pocket[i].cur, (u8)pocket[i].scr );
  }

  // 現在のポケット位置を保存
  MyItem_FieldBagPocketSet( wk->dat->bag_cursor, pocket[wk->dat->p_now].type );
}


//--------------------------------------------------------------------------------------------
/**
 * アイテムリスト作成
 *
 * @param wk    バッグ画面ワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void ItemListDataMake( BAG_WORK * wk )
{
  POCKET_DATA * pocket;
  u32 i,count=0;

  pocket = &wk->dat->p_data[wk->dat->p_now];


  // 技ポケットの時
  if( pocket->type == BAG_POKE_WAZA ){
    for( i=0; i<PocketMax[pocket->type]; i++ ){
      if( pocket->item[i].id == 0 || pocket->item[i].no == 0 ){
        break;
      }
      BAG_GetItemWazaName( wk->waza_man, wk->itemname[i], pocket->item[i].id, HEAPID_BAG );
      wk->exist_item[count] = pocket->item[i].id;
      count++;
    }
    pocket->max = i;

  // どうぐポケットの時
  }else{
    for( i=0; i<PocketMax[pocket->type]; i++ ){
      if( pocket->item[i].id == 0 || pocket->item[i].no == 0 ){
        break;
      }
      BAG_GetItemName( wk->item_man, wk->itemname[i], pocket->item[i].id, HEAPID_BAG );
      wk->exist_item[count] = pocket->item[i].id;
      count++;
    }
    if( wk->dat->mode != BAG_MODE_MIX_SIO ){
      pocket->max = i;
    }else{
      pocket->max = i;
    }
  }

  { // 最大数とスクロールカウンタをチェック
    int tmp;

    if( pocket->max == 0 ){
      tmp = 0;
    }else{
      tmp = ( pocket->max - 1 ) / 6 * 6;
    }
    if( pocket->scr > tmp ){
      pocket->scr = tmp;
    }
  }
}

//--------------------------------------------------------------------------------------------
/**
 * アイテムリストのアイテム名を格納する場所を確保
 *
 * @param wk    バッグ画面ワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void ItemListStrAlloc( BAG_WORK * wk )
{
  u32 i;

  for( i=0; i<BAG_LARGE_POKE_MAX; i++ ){
    wk->itemname[i] = STRBUF_Create( BUFLEN_ITEM_NAME, HEAPID_BAG );
  }
}

//--------------------------------------------------------------------------------------------
/**
 * アイテムリストのアイテム名を解放
 *
 * @param wk    バッグ画面ワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void ItemListStrFree( BAG_WORK * wk )
{
  u32 i;

  for( i=0; i<BAG_LARGE_POKE_MAX; i++ ){
    STRBUF_Delete( wk->itemname[i] );
  }
}

//--------------------------------------------------------------------------------------------
/**
 * スクロールカウンタ、カーソル位置の修正
 *
 * @param scr     スクロールカウンタ
 * @param pos     カーソル位置
 * @oaram buf_max   bufに入っているデータの数
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void ItemListParamReset( s16 * scr, u16 * pos, u8 buf_max )
{
#if 0
  u8  pos_max;

  buf_max -= 1; // 最後のラベル分をマイナス

  if( buf_max > 8 ){
    pos_max = 8 - 1;
  }else{
    pos_max = buf_max-1;
  }

  if( *scr != 0 ){
    if( *scr + pos_max > buf_max-1 ){
      *scr = buf_max-1 - pos_max;
    }
  }

  if( *scr + *pos >= buf_max-1 ){
    *pos = buf_max-1 - *scr;
  }
#endif

  MORI_PRINT( "ItemListReset scr=%d, pos=%d, max=%d\n", *scr, *pos, buf_max );

  if( *scr + *pos > buf_max ){
//    *scr -= BAG_PAGE_ITEM_NUM;
//    *scr = buf_max-1 - *pos;
    *scr = (buf_max-1)/BAG_PAGE_ITEM_NUM * BAG_PAGE_ITEM_NUM;
//    *pos += (BAG_PAGE_ITEM_NUM-1);
  }

  // せっかく引いたのにマイナスになっているのであれば０に
  if(*scr<0){
    *scr = 0;
  }

}

//--------------------------------------------------------------------------------------------
/**
 * スクロールカウンタ、カーソル位置の修正（全体）
 *
 * @param wk    バッグ画面ワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void ItemListParamResetAll( BAG_WORK * wk )
{
  u32 i;

  for( i=0; i<wk->p_max; i++ ){
    ItemListParamReset(
      &wk->dat->p_data[i].scr, &wk->dat->p_data[i].cur, wk->dat->p_data[i].max );
  }
}


//--------------------------------------------------------------------------------------------
/**
 * BMPリストのカーソル位置の修正
 *
 * @param scr     スクロールカウンタ
 * @param pos     カーソル位置
 * @oaram buf_max   bufに入っているデータの数
 * @param list_max  BMPリストの表示最大数
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void ItemListCurPosReset( s16 * scr, u16 * pos, u8 buf_max, u8 list_max )
{
  u8 pos_max;
  u8  i;


  if(*scr>buf_max && *scr>0){
    *scr--;
  }

#if 0
  buf_max -= 1; // 最後のラベル分をマイナス

  if( buf_max > (list_max-1) ){
    pos_max = (list_max-2);
  }else{
    pos_max = buf_max-1;
  }

  if( !( *pos >= ( list_max >> 1 ) + 2 ) ){ return; }

  for( i=0; i<=*pos-(list_max>>1)-2; i++ ){
    if( *scr+pos_max == buf_max-1 ){
      break;
    }
    *pos -= 1;
    *scr += 1;
  }
#endif
}

//--------------------------------------------------------------------------------------------
/**
 * BMPリストのカーソル位置の修正（全体）
 *
 * @param wk    バッグ画面ワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void ItemListCurPosResetAll( BAG_WORK * wk )
{
  u32 i;

  for( i=0; i<wk->p_max; i++ ){
    ItemListCurPosReset(
      &wk->dat->p_data[i].scr, &wk->dat->p_data[i].cur, wk->dat->p_data[i].max, ONE_PAGE_LIST_MAX );
  }
}


//------------------------------------------------------------------
/**
 * @brief   このポケットで今表示できるどうぐの数を返す
 *
 * @param   wk    バッグ画面ワーク
 *
 * @retval  int
 */
//------------------------------------------------------------------
static int _get_page_button_num( BAG_WORK *wk )
{
  int num = wk->dat->p_data[wk->dat->p_now].max - wk->dat->p_data[wk->dat->p_now].scr;
  if(num>6){
    num = BAG_PAGE_ITEM_NUM;
  }

  return num;
}

//------------------------------------------------------------------
/**
 * @brief   ページ切り替えの際に入れ替えどうぐはページ内にあるか
 *
 * @param   wk    バッグ画面ワーク
 *
 * @retval  int   0-5:ある  -1:無い
 */
//------------------------------------------------------------------
static int _get_inpage_target( BAG_WORK *wk )
{
  int scr     = wk->dat->p_data[wk->dat->p_now].scr;
  int itempos = wk->irekae_pos;

  if((itempos/6)*6 == scr){
    return itempos%6;
  }
  return -1;
}

//--------------------------------------------------------------------------------------------
/**
 * アイテムリストセット
 *
 * @param wk    バッグ画面のワーク
 * @param scr   スクロール位置
 * @param pos   カーソル位置
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void ItemListSet( BAG_WORK * wk, s16 scr, u16 pos )
{
  // どうぐ名描画
  BagBmp_ItemNamePrint( wk, scr, -1, ITEMPRINT_NORMAL );

  PageSet( wk, BAG_PAGE_NORMAL, _get_page_button_num(wk), 0 );
  BgObj_PocketPalSet( wk, wk->dat->p_now );
  BAG_BackGroundPalChange( wk, 1, wk->dat->p_now );
  BagBmp_PageNoPrint( wk, wk->dat->p_data[wk->dat->p_now].max,
              wk->dat->p_data[wk->dat->p_now].scr, 0 );
  BagObj_ItemIconSet( wk, &wk->dat->p_data[wk->dat->p_now], _get_page_button_num(wk), 1 );


#if 0
  BMPLIST_HEADER  list_h;

  list_h = BagItemList;
  list_h.list  = wk->ld;
  list_h.win   = &wk->win[WIN_LIST];
  list_h.count = wk->dat->p_data[wk->dat->p_now].max;
  list_h.work  = (void *)wk;
  if( wk->dat->p_data[wk->dat->p_now].type == BAG_POKE_WAZA ||
    wk->dat->p_data[wk->dat->p_now].type == BAG_POKE_NUTS ){
    list_h.data_x = LIST_PX_WAZAMACHINE;
  }else{
    list_h.data_x = LIST_PX_NORMAL;
  }
  wk->lw = BmpListSet( &list_h, scr, pos, HEAPID_BAG );

  GF_BGL_BmpWinOnVReq( &wk->win[WIN_LIST] );
#endif
}



//--------------------------------------------------------------------------------------------
/**
 * アイテムリスト破棄
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void ItemListExit( BAG_WORK * wk )
{
//  BmpListExit(
//    wk->lw, &wk->dat->p_data[wk->dat->p_now].scr, &wk->dat->p_data[wk->dat->p_now].cur );
//  BMP_MENULIST_Delete( wk->ld );
  wk->lw = NULL;
}


//------------------------------------------------------------------
/**
 * @brief   リスト内にカーソル位置がある場合は保存する
 *
 * @param   wk    バッグ画面ワーク
 * @param   pos   カーソル位置
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void _cursor_pos_backup( BAG_WORK *wk, int pos )
{
  if(pos>=8 && pos<14){
    wk->dat->p_data[wk->dat->p_now].cur = pos-8;
  }
}


//------------------------------------------------------------------
/**
 * @brief   カーソル移動が発生しない場合のチェック
 *
 * @param   wk    バッグ画面ワーク
 * @param touch タッチ位置
 *
 * @retval  int   1:移動する 0:移動しない
 */
//------------------------------------------------------------------
static int _touch_no_move_check( BAG_WORK *wk, int touch )
{
  // 矢印OBJをタッチしている場合はカーソルは動かない
  if( touch==CURSORPOS_SUBPAGE || touch==CURSORPOS_ADDPAGE){
    return 0;
  }

  // カーソルがどうぐリスト側にあるときは動かない
  if(touch<=CURSORPOS_POCKET7){
    if(  wk->cursor_pos>=CURSORPOS_ITEM0
      && wk->cursor_pos<=CURSORPOS_ITEM5){
      return 0;
    }
  }

  return 1;
}


//==============================================================================
/**
 * @brief   カーソルが示しているどうぐのIDを返す
 *
 * @param   wk    バッグ画面ワーク
 *
 * @retval  u16
 */
//==============================================================================
static u16 _get_item_id( BAG_WORK *wk )
{
  POCKET_DATA *pocket = &wk->dat->p_data[wk->dat->p_now];
  u32 pos = pocket->scr+wk->cursor_pos-8;

#ifdef PRINT_BAG_DATA

//  OS_Printf("now=%d, pos=%d, PocketMax=%d, id=%d\n",wk->dat->p_now,wk->cursor_pos-8,PocketMax[wk->dat->p_now],pocket->item[pos].id);
  {
    int i;
    for(i=0;i<PocketMax[wk->dat->p_now];i++){
      OS_Printf("id=%d,num=%d\n",pocket->item[i].id, pocket->item[i].no );
    }
  }
#endif

  if( PocketMax[wk->dat->p_now] <= pos ){
    return 0;
  }
  return pocket->item[pos].id;
}


//------------------------------------------------------------------
/**
 * @brief   どうぐ説明描画（書かないときは消す）
 *
 * @param   wk    バッグ画面ワーク
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void _item_explain_put( BAG_WORK *wk )
{
  if( wk->cursor_pos >= CURSORPOS_ITEM0 && wk->cursor_pos <= CURSORPOS_ITEM5 ){
    // 選択したどうぐの説明文章を上画面に表示する
    u16 item_id = _get_item_id(wk);
    if(item_id!=0){
      BagBmp_ItemExplainPut( wk, &wk->win[WIN_INFO], item_id );
    }else{
      BagBmp_ItemExplainClear( wk, &wk->win[WIN_INFO] );
    }
  // ポケットを指定している
  }else if( wk->cursor_pos >= CURSORPOS_POCKET0 && wk->cursor_pos <= CURSORPOS_POCKET7 ){
    BagBmp_PocketExplainPut( wk, &wk->win[WIN_INFO], wk->cursor_pos );
  // アイテムがない場所なら表示しない
  }else{
    BagBmp_ItemExplainClear( wk, &wk->win[WIN_INFO] );
  }
}

//--------------------------------------------------------------------------------------------
/**
 * メインコントロール
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  シーケンス
 */
//--------------------------------------------------------------------------------------------
static int MainSeqFunc( BAG_WORK * wk )
{
  int refresh = 0;
  POCKET_DATA *pocket = &wk->dat->p_data[wk->dat->p_now];

  // カーソル移動
  if(sys.repeat & PAD_KEY_UP){
    wk->cursor_pos = _key_table[wk->cursor_pos].up;
    refresh++;
  }else if(sys.repeat & PAD_KEY_DOWN){
    wk->cursor_pos = _key_table[wk->cursor_pos].down;
    refresh++;
  }else if(sys.repeat & PAD_KEY_LEFT){
    if(_key_table[wk->cursor_pos].left==14){
      u8 ret;
      return DecideFunc( wk, CURSORPOS_SUBPAGE, &ret, 1, BAG_PAGE_SELECT, APP_END_KEY);
    }else if( wk->cursor_pos != 16 ){
      if( wk->cursor_pos >= 0 && wk->cursor_pos < BAG_POCKET_NUM ){
        int tmp_pos = _next_pocket( wk, wk->cursor_pos, -1 );
        if( wk->cursor_pos != tmp_pos ){
          wk->cursor_pos = tmp_pos;
          refresh++;
        }
      }else{
        wk->cursor_pos = _key_table[wk->cursor_pos].left;
        refresh++;
      }
    }
  }else if(sys.repeat & PAD_KEY_RIGHT){
    if(_key_table[wk->cursor_pos].right==15){
      u8 ret;
      return DecideFunc( wk, CURSORPOS_ADDPAGE, &ret, 1, BAG_PAGE_SELECT, APP_END_KEY);
    }else if( wk->cursor_pos != 16 ){
      if( wk->cursor_pos >= 0 && wk->cursor_pos < BAG_POCKET_NUM ){
        int tmp_pos = _next_pocket( wk, wk->cursor_pos, 1 );
        if( wk->cursor_pos != tmp_pos ){
          wk->cursor_pos = tmp_pos;
          refresh++;
        }
      }else{
        wk->cursor_pos = _key_table[wk->cursor_pos].right;
        refresh++;
      }
    }
  }else if( sys.trg & PAD_BUTTON_L){
    u8 ret;

    if( wk->cursor_pos >= 0 && wk->cursor_pos < BAG_POCKET_NUM ){
      wk->cursor_pos = _next_pocket( wk, wk->dat->p_now, -1 );
      BgObj_CursorPosAppearSet( wk, wk->cursor_pos );
      return DecideFunc( wk, wk->cursor_pos, &ret, 1, BAG_PAGE_SELECT, APP_END_KEY );
    }else{
      return DecideFunc( wk, _next_pocket(wk,wk->dat->p_now,-1), &ret, 1, BAG_PAGE_SELECT, APP_END_KEY);
    }
  }else if( sys.trg & PAD_BUTTON_R){
    u8 ret;

    if( wk->cursor_pos >= 0 && wk->cursor_pos < BAG_POCKET_NUM ){
      wk->cursor_pos = _next_pocket( wk, wk->dat->p_now, 1 );
      BgObj_CursorPosAppearSet( wk, wk->cursor_pos );
      return DecideFunc( wk, wk->cursor_pos, &ret, 1, BAG_PAGE_SELECT, APP_END_KEY );
    }else{
      return DecideFunc( wk, _next_pocket(wk,wk->dat->p_now,1), &ret, 1, BAG_PAGE_SELECT, APP_END_KEY);
    }
  }

  // 移動先が「CURSORPOS_POCKETS」だった場合は現在選択中のポケットに移動させる
  if(wk->cursor_pos==CURSORPOS_POCKETS){
    wk->cursor_pos = wk->dat->p_now;
  }

  // カーソル移動が発生している
  if(refresh){
    Snd_SePlay( BAG_SE_LIST_MOVE1 );
    BgObj_CursorPosAppearSet( wk, wk->cursor_pos );
    // ポケット毎のカーソル位置保存
    _cursor_pos_backup( wk, wk->cursor_pos );
    // アイテム説明描画
    _item_explain_put( wk );
  }


  // アイテム選択
  {
    u8  ret = LIST_SEL_NONE;
    u32 touch;

    // 決定
    if((touch=TouchButtonControl( wk, TOUCH_MODE_NORMAL ))!=RECT_HIT_NONE){
      int result;

      // ページ切り替えの時はカーソルは移動しない
      if( _touch_no_move_check(wk,touch) ){
        if( touch >= 0 && touch < BAG_POCKET_NUM ){
          if( _pocket_search( wk, touch ) != -1 ){
            wk->cursor_pos = touch;
            BgObj_CursorPosAppearSet( wk, wk->cursor_pos );
          }
        }else{
          wk->cursor_pos = touch;
          BgObj_CursorPosAppearSet( wk, wk->cursor_pos );
          if( wk->cursor_pos >= CURSORPOS_ITEM0 && wk->cursor_pos <= CURSORPOS_ITEM5 ){
            _cursor_pos_backup( wk, wk->cursor_pos );
          }
        }
      }
      result = DecideFunc( wk, touch, &ret, 1, BAG_PAGE_SELECT, APP_END_TOUCH);
      if( result!=SEQ_MAIN ){
        return result;
      }
    }else if( sys.trg & PAD_BUTTON_DECIDE ){
      int result;
      result = DecideFunc( wk, wk->cursor_pos, &ret, 1, BAG_PAGE_SELECT, APP_END_KEY);
      if( wk->cursor_pos >= CURSORPOS_ITEM0 && wk->cursor_pos <= CURSORPOS_ITEM5 ){
        _cursor_pos_backup( wk, wk->cursor_pos );
      }
      if( result!=SEQ_MAIN ){
        return result;
      }
    }else if(sys.trg & PAD_BUTTON_CANCEL){
      int result = DecideFunc( wk, CURSORPOS_END, &ret, 1, BAG_PAGE_SELECT, APP_END_KEY);
      _set_keytouch_status(wk, APP_END_KEY);
      if( wk->cursor_pos >= CURSORPOS_ITEM0 && wk->cursor_pos <= CURSORPOS_ITEM5 ){
        _cursor_pos_backup( wk, wk->cursor_pos );
      }
      if( result!=SEQ_MAIN ){
        return result;
      }
    }

    if( ret == LIST_SEL_ITEM ){     // 選択された
      return ButtonAnmSet( wk, ACT_BAG_CURSOR, 41, SEQ_MENU_INIT );
    }
  }

  return SEQ_MAIN;
}

//--------------------------------------------------------------------------------------------
/**
 * メニュー画面へ切り替え
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  シーケンス
 */
//--------------------------------------------------------------------------------------------
static int MenuPageChange( BAG_WORK * wk )
{
  POCKET_DATA * pocket = &wk->dat->p_data[wk->dat->p_now];

  PageSet( wk, BAG_PAGE_SELECT, 0, 0 );

  // 下画面中央に名前・個数表示
  BagBmp_SelectItemPrint( wk, pocket->scr, wk->cursor_pos-8 );
  BagObj_SelectItemMove( wk, wk->cursor_pos-8 );

  // 選択肢表示
  ItemMenuMake( wk );

  // 選択したどうぐの情報を取得
  wk->dat->ret_item = (u16)pocket->item[pocket->scr+wk->cursor_pos-8].id; // 選択アイテム
  wk->sel_max   = (u16)pocket->item[pocket->scr+wk->cursor_pos-8].no;   // 所持数

  return SEQ_MENU;
}

//--------------------------------------------------------------------------------------------
/**
 * アイテムリストのページ切り替え
 *
 * @param wk    バッグ画面のワーク
 * @param mv    移動方向
 *
 * @return  シーケンス
 */
//--------------------------------------------------------------------------------------------
static int ItemListPageChange( BAG_WORK * wk, s8 mv )
{
  POCKET_DATA * p = &wk->dat->p_data[wk->dat->p_now];

  if( mv > 0 ){
    // カーソルはループする
    if( p->scr+6 < p->max ){
      p->scr += 6;
    }else{
      p->scr = 0;
    }
  }else{
    // カーソルはループする
    if( p->scr-6 >= 0 ){
      p->scr -= 6;
    }else{
      p->scr = ((p->max-1)/6)*6;
    }
  }

  if( wk->irekae_flg == 1 ){
    item_change_page_refresh( wk, p );
    BgObj_InsertCursorPosAppearSet( wk, wk->select_cursor_pos );
    return SEQ_IREKAE;
  }

  _itemlist_update( wk, p );    // どうぐリスト更新
  _item_explain_put( wk );    // アイテム説明描画

  // モードで分岐
  switch(wk->dat->mode){
  case BAG_MODE_ITEMSALE:
    return SEQ_SALE_MAIN;
  case BAG_MODE_ITEMSET:
    return SEQ_ITEMSET_MAIN;
  case BAG_MODE_KINOMI:
    return SEQ_KINOMISEL_MAIN;
  }
  return SEQ_MAIN;
}

//--------------------------------------------------------------------------------------------
/**
 * ポケットカーソル移動のためのデータを作成
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  none
 *
 * @li  wk->p_icon_gx = 一番左のポケットアイコンのX座標
 * @li  wk->p_icon_sx = ポケットアイコン同士の間隔
 */
//--------------------------------------------------------------------------------------------
static void PocketIconXmake( BAG_WORK * wk )
{
  wk->p_icon_gx =
    P_ICON_DEF_PX + ( P_ICON_DEF_SX - ( P_ICON_SIZ_X * wk->p_max ) ) / ( wk->p_max + 1 );
  wk->p_icon_sx = P_ICON_SIZ_X + wk->p_icon_gx - P_ICON_DEF_PX;
}


static int debugno   = 0;
static int debugpage = 0;
static int debugnum  = 1;
static int debugtarget = 0;

//--------------------------------------------------------------------------------------------
/**
 * ポケットコントロール
 *
 * @param wk    バッグ画面のワーク
 *
 * @retval  "TRUE = キー入力あり"
 * @retval  "FALSE = キー入力なし"
 */
//--------------------------------------------------------------------------------------------
static u8 PocketControl( BAG_WORK * wk )
{
  int refresh=0;

  if(sys.trg & PAD_BUTTON_DEBUG){
    debugtarget++;
    if(debugtarget>=debugnum){
      debugtarget = 0;
    }
    PageSet( wk, BAG_PAGE_INSERT, debugnum, debugtarget );
  }

  return FALSE;
}

//==============================================================================
/**
 * @brief   どうぐポケット情報が登録されているか検索して返す
 *
 * @param   wk    バッグワーク
 * @param   pos   どうぐポケットの指定番号
 *
 * @retval  int   1:指定のどうぐポケットは登録されている 0:ない
 */
//==============================================================================
static int _pocket_search( BAG_WORK *wk, int pos )
{
  int i;
  for(i=0;i<BAG_POCKET_NUM;i++){
    if( wk->dat->p_data[i].type == pos && wk->dat->p_data[i].item!=NULL ){
      return i;
    }
  }
  return -1;
}

//--------------------------------------------------------------------------------------------
/**
 * 次のポケットを取得
 *
 * @param wk    バッグ画面のワーク
 * @param pos   現在のポケット
 * @param mv    切り替え方向
 *
 * @return  ポケット番号
 */
//--------------------------------------------------------------------------------------------
static int _next_pocket( BAG_WORK * wk, int pos, int mv )
{
  int i;

  for( i=0; i<BAG_POCKET_NUM; i++ ){
    pos += mv;
    if( pos < 0 ){
      pos = BAG_POCKET_NUM - 1;
    }else if( pos == BAG_POCKET_NUM ){
      pos = 0;
    }
    if( _pocket_search( wk, pos ) != -1 ){
      break;
    }
  }

  return pos;
}

//------------------------------------------------------------------
/**
 * @brief   パッグのどうぐリスト更新
 *
 * @param   wk    バッグ画面ワーク
 * @param   p   ポケットデータ
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void _itemlist_update( BAG_WORK *wk, POCKET_DATA *p )
{
  PageSet( wk, BAG_PAGE_NORMAL, _get_page_button_num(wk), 0 );
  BagBmp_ItemNamePrint( wk, p->scr, -1, ITEMPRINT_NORMAL );
  BagBmp_PageNoPrint( wk, p->max, p->scr, 0 );
  BagObj_ItemIconSet( wk, p, _get_page_button_num(wk),1 );

}
//------------------------------------------------------------------
/**
 * @brief   通常リスト状態で決定した時
 *
 * @param   wk    バッグ画面ワーク
 * @param   pos   カーソル位置
 * @param   ret   選択時に書き換えを行う状態変数のポインタ
 * @param   mode  選択時にページ切り替えを行うか(0:行わない　1:行う）
 * @param   page  どうぐ選択時にメニューに行くか数値指定にいくか（BAG_PAGE_SELECT or BAG_PAGE_SUB)
 * @param   keytouch  決定をキーとタッチのどちらで行ったか
 *
 * @retval  none
 */
//------------------------------------------------------------------
static int DecideFunc( BAG_WORK *wk, int pos, u8 *ret, int mode, int page, int keytouch )
{
  int result = SEQ_MAIN;
  switch(pos){

  // ポケット選択

  case CURSORPOS_POCKET0: case CURSORPOS_POCKET1: case CURSORPOS_POCKET2: case CURSORPOS_POCKET3:
  case CURSORPOS_POCKET4: case CURSORPOS_POCKET5: case CURSORPOS_POCKET6: case CURSORPOS_POCKET7:


    // ポケットが登録されていない場合はポケット切り替え却下
    if( (pos = _pocket_search( wk, pos )) == -1 ){
      return result;
    }

    // ポケットが同じ場合でキー操作のときは切り替える必要なし
    if( pos == wk->dat->p_now && keytouch == APP_END_KEY ){
      return result;
    }

    // ポケットが存在する
    wk->dat->p_now = pos;
    ItemListDataMake( wk );       // アイテムリスト作成

    {
      POCKET_DATA *p = &wk->dat->p_data[wk->dat->p_now];
      PageSet( wk, BAG_PAGE_NORMAL, _get_page_button_num(wk), 0 );

      BagBmp_ItemNamePrint( wk, p->scr, -1, ITEMPRINT_NORMAL );

      BgObj_PocketPalSet( wk, wk->dat->p_now );
      BagBmp_PageNoPrint( wk, p->max, p->scr, 0 );
      BagObj_ItemIconSet( wk, p, _get_page_button_num(wk), 1 );
      BAG_BackGroundPalChange( wk, 1, wk->dat->p_now );
      Snd_SePlay( BAG_SE_POCKET_MOVE );
      // アイテム説明描画
      _item_explain_put( wk );

    }

    // ポケット毎のカーソル位置保存
    if( wk->cursor_pos >= BAG_POCKET_NUM ){
      _cursor_pos_backup( wk, wk->cursor_pos );
    }

    // バッグ３ＤＯＢＪ切り替え
    Bag3DObjAnmChg( wk );
    // 3Dカメラ移動設定
    CameraMoveStart( &wk->wk3d, wk->dat->p_now+1, CAMERA_MOVE_FRAME );

    break;
  // どうぐ選択
  case CURSORPOS_ITEM0: case CURSORPOS_ITEM1: case CURSORPOS_ITEM2:
  case CURSORPOS_ITEM3: case CURSORPOS_ITEM4: case CURSORPOS_ITEM5:
    {
      int itempos = pos-8;
      POCKET_DATA * pocket;
      pocket = &wk->dat->p_data[wk->dat->p_now];

      OS_Printf("max=%d, now=%d", pocket->max, pocket->scr+pos);

      if( pocket->scr+itempos < pocket->max){

        wk->dat->ret_item = (u16)pocket->item[pocket->scr+itempos].id;  // 選択アイテム

        // リストを選択した事を通知
        *ret = LIST_SEL_ITEM;
        Snd_SePlay( BAG_SE_ITEM_SELECT );
      }
      // アイテム説明描画
      _item_explain_put( wk );
    }
    break;

  // 右矢印
  case CURSORPOS_ADDPAGE:
    {
      POCKET_DATA *p = &wk->dat->p_data[wk->dat->p_now];
      // どうぐが6個以下ならページ切り替えなし
      if(p->max<=6){
        break;
      }
    }
    Snd_SePlay( BAG_SE_ITEM_SELECT );
    result = ButtonPalAnmSet( wk, ACT_BAG_DOWN_BUTTON, 9, 8, SEQ_LIST_ADD );
    break;

  // 左矢印
  case CURSORPOS_SUBPAGE:
    {
      POCKET_DATA *p = &wk->dat->p_data[wk->dat->p_now];
      // どうぐが６個以下ならページ切り替えなし
      if(p->max<=6){
        break;
      }
    }
    Snd_SePlay( BAG_SE_ITEM_SELECT );
    result = ButtonPalAnmSet( wk, ACT_BAG_UP_BUTTON, 9, 8, SEQ_LIST_SUB );
    break;

  // やめる
  case CURSORPOS_END:
    wk->dat->ret_item = 0;
    wk->dat->ret_mode = BAG_RET_CANCEL; // 終了モード
    _set_keytouch_status(wk, keytouch);
    Snd_SePlay( BAG_SE_CLOSE );
    result = ButtonPalAnmSet( wk, ACT_BAG_BACK_BUTTON, 9, 8, SEQ_OUT_SET );
    break;
  }

  return result;
}


//--------------------------------------------------------------------------------------------
/**
 * ポケット切り替え共通初期処理
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void PocketChangeInitKey( BAG_WORK * wk )
{
  PocketChangeInit( wk );
  wk->page_work.tp_seq  = 3;
  wk->page_work.tp_mode = 0;
}

//--------------------------------------------------------------------------------------------
/**
 * 下画面のボタンでポケット切り替え
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void PocketChangeInitTp( BAG_WORK * wk )
{
  if( wk->page_work.move != 2 ){
    PocketChangeInit( wk );
  }else{
    wk->page_work.cur_seq = 2;
  }
  wk->page_work.tp_seq  = 0;
  wk->page_work.tp_mode = 1;
}

//--------------------------------------------------------------------------------------------
/**
 * ポケット切り替え
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void PocketChangeInit( BAG_WORK * wk )
{
  PAGE_CHG_WORK * pwk = &wk->page_work;

  pwk->cur_seq = 0;
  pwk->cur_cnt = 0;
  pwk->tp_cnt  = 0;
  pwk->tp_chg  = 0;
  pwk->tp_push = 0;

  ItemListExit( wk );
  GF_BGL_BmpWinDataFill( &wk->win[WIN_INFO], 0 );
  GF_BGL_BmpWinOnVReq( &wk->win[WIN_INFO] );
}

//--------------------------------------------------------------------------------------------
/**
 * ポケット切り替え処理
 *
 * @param wk    バッグ画面のワーク
 *
 * @retval  "TRUE = 切り替え終了"
 * @retval  "FALSE = 切り替え中"
 */
//--------------------------------------------------------------------------------------------
static u8 PocketChange( BAG_WORK * wk )
{
  PAGE_CHG_WORK * pwk;
  int tp_ret;
  u8  cur_ret;

  pwk = &wk->page_work;

  // タッチパネルに触っているか
  if( GF_TP_GetCont() == FALSE ){ // 触れていない
    pwk->tp_push = 1;
  }

  // タッチ位置の確認
  tp_ret = SubPokeButtonEndCheck( wk );
  if( tp_ret == RECT_HIT_NONE || tp_ret != pwk->next ){
    pwk->tp_chg = 1;
  }

  // 十字キーチェック
  if( PocketChangeReset( wk ) == FALSE ){
    // タッチパネルチェック
    if( pwk->tp_push == 1 && tp_ret != RECT_HIT_NONE ){

      wk->dat->p_now = pwk->next;

      if( pwk->next > (u8)tp_ret ){
        pwk->move    = 0;
        pwk->cur_seq = 0;
//        Bag_PocketIconPut( wk, pwk->next, 0 );
      }else if( pwk->next < (u8)tp_ret ){
        pwk->move    = 1;
        pwk->cur_seq = 0;
//        Bag_PocketIconPut( wk, pwk->next, 0 );
      }else{
        pwk->move= 2;
      }

      pwk->next = (u8)tp_ret;
      pwk->tp_chg  = 0;
      pwk->tp_push = 0;
      pwk->tp_seq  = 0;

      wk->p_next = (u8)tp_ret;
      BagPocketCursorMoveInit( wk );

      // 3Dカメラ移動設定
      CameraMoveStart( &wk->wk3d, wk->p_next+1, CAMERA_MOVE_FRAME );
    }
  }

  // エフェクト
  cur_ret = PocketCursorMove( wk );

  BagPocketCursorMoveMain( wk );

  return FALSE;
}

//--------------------------------------------------------------------------------------------
/**
 * ポケット再切り替えチェック
 *
 * @param wk    バッグ画面のワーク
 *
 * @retval  "TRUE = 再切り替え"
 * @retval  "FALSE = なにもしない"
 */
//--------------------------------------------------------------------------------------------
static u8 PocketChangeReset( BAG_WORK * wk )
{
  PAGE_CHG_WORK * pwk = &wk->page_work;

  if( sys.trg & PAD_KEY_LEFT ){
    if( wk->p_max == 1 ){ return TRUE; }
    Snd_SePlay( BAG_SE_POCKET_MOVE );
//    CATS_ObjectAnimeSeqSetCap( wk->cap[ACT_BAG], wk->dat->p_data[pwk->next].type );

    wk->dat->p_now = pwk->next;

    if( pwk->next != 0 ){
      pwk->next = pwk->next - 1;
      wk->p_next = wk->p_next - 1;
    }else{
      pwk->next = wk->p_max - 1;
      wk->p_next = wk->p_max - 1;
    }

    pwk->cur_seq = 0;
    pwk->move    = 0;

    pwk->tp_push = 1;
    pwk->tp_chg  = 1;
    pwk->tp_mode = 0;

    if( pwk->tp_seq != 3 ){ pwk->tp_seq = 4; }


    BagPocketCursorMoveInit( wk );

    return TRUE;
  }
  if( sys.trg & PAD_KEY_RIGHT ){
    if( wk->p_max == 1 ){ return TRUE; }
    Snd_SePlay( BAG_SE_POCKET_MOVE );
//    CATS_ObjectAnimeSeqSetCap( wk->cap[ACT_BAG], wk->dat->p_data[pwk->next].type );

    wk->dat->p_now = pwk->next;

    if( pwk->next+1 < wk->p_max ){
      pwk->next = pwk->next + 1;
      wk->p_next = wk->p_next + 1;
    }else{
      pwk->next = 0;
      wk->p_next = 0;
    }

    pwk->cur_seq = 0;
    pwk->move    = 1;

    pwk->tp_push = 1;
    pwk->tp_chg  = 1;
    pwk->tp_mode = 0;

    if( pwk->tp_seq != 3 ){ pwk->tp_seq = 4; }

    BagPocketCursorMoveInit( wk );

    return TRUE;
  }
  return FALSE;
}

//--------------------------------------------------------------------------------------------
/**
 * ポケットカーソル移動
 *
 * @param wk    バッグ画面のワーク
 *
 * @retval  "TRUE = 移動完了"
 * @retval  "FALSE = 移動中"
 */
//--------------------------------------------------------------------------------------------
static u8 PocketCursorMove( BAG_WORK * wk )
{
  PAGE_CHG_WORK * pwk = &wk->page_work;

  switch( pwk->cur_seq ){
  case 0:   // 初期化
    pwk->cur_cnt = 0;
    pwk->cur_seq++;
    break;

  case 1:   // 移動
    if( pwk->cur_cnt < 8 ){
      pwk->cur_cnt++;
    }else{
      if( wk->lw != NULL ){
      }
      wk->dat->p_now = pwk->next;

      ItemListDataMake( wk );
      BagBmp_ItemNamePrint( wk, wk->dat->p_data[wk->dat->p_now].scr, -1, ITEMPRINT_NORMAL );
      PageSet( wk, BAG_PAGE_NORMAL, _get_page_button_num(wk), 0 );
      BgObj_PocketPalSet( wk, wk->dat->p_now );
      BAG_BackGroundPalChange( wk, 1, wk->dat->p_now );

      OS_Printf( "page = %d\n", wk->dat->p_now );

      ItemListParamReset(
        &wk->dat->p_data[wk->dat->p_now].scr,
        &wk->dat->p_data[wk->dat->p_now].cur,
        wk->dat->p_data[wk->dat->p_now].max );
      ItemListCurPosReset(
        &wk->dat->p_data[wk->dat->p_now].scr,
        &wk->dat->p_data[wk->dat->p_now].cur,
        wk->dat->p_data[wk->dat->p_now].max, ONE_PAGE_LIST_MAX );

      pwk->cur_seq++;
      return TRUE;
    }
    break;

  case 2:   // 終了
    return TRUE;
  }

  return FALSE;
}

//--------------------------------------------------------------------------------------------
/**
 * ボタンコントロール
 *
 * @param wk    バッグ画面のワーク
 * @param   mode    TOUCH_MODE_NORMAL=0,  // 通常時
 *          TOUCH_MODE_SELECT,    // どうぐ選択後の選択肢表示
 *          TOUCH_MODE_CHANGE,    // どうぐ入れ替え時
 *          TOUCH_MODE_NUMBER,    // 数値入力時
 *
 *
 * @retval  "TRUE = 押された"
 * @retval  "FALSE = 押されていない"
 */
//--------------------------------------------------------------------------------------------
static u32 TouchButtonControl( BAG_WORK * wk, int mode )
{
  static const RECT_HIT_TBL *TouchTable[]={
    TouchButtonNormalTbl,       // 通常時
    TouchButtonSelectTbl,       // どうぐ選択後の選択肢表示
    TouchButtonChangeTbl,   // どうぐ入れ替え時
    TouchButtonNumInputTbl,   // 数値入力時
    TouchButtonSaleNumInputTbl,   // 数値入力時
  };

  int ret = GF_TP_RectHitTrg( TouchTable[mode] );

//  int ret = SubPokeButtonCheck( wk );

  if(ret!=RECT_HIT_NONE){
    MORI_PRINT("touch  = %d\n", ret);
  }

  return ret;
}


//--------------------------------------------------------------------------------------------
/**
 * タッチパネルのボタン放し判定
 *
 * @param wk    バッグ画面のワーク
 *
 * @retval  "RECT_HIT_NONE = 放した"
 * @retval  "RECT_HIT_NONE != 押されている"
 */
//--------------------------------------------------------------------------------------------
static int SubPokeButtonEndCheck( BAG_WORK * wk )
{
//  int ret = GF_TP_RectHitCont( PokeButtonPos[ wk->p_max ].rect_tbl );
//  int ret = GF_TP_HitCont( PokeButtonPos[ wk->p_max ].rect_tbl );
  int ret = RECT_HIT_NONE;

  if( ret != RECT_HIT_NONE ){
    u16 pat = 0xfffe;

    if( GF_BGL_DotCheck( wk->bgl, GF_BGL_FRAME0_S, sys.tp_x, sys.tp_y, &pat ) == FALSE ){
      return RECT_HIT_NONE;
    }
  }

  return ret;
}









//============================================================================================
//============================================================================================
//  入れ替え
//============================================================================================
//============================================================================================

//--------------------------------------------------------------------------------------------
/**
 * 入れ替え可能かをチェック
 *
 * @param wk    バッグ画面のワーク
 *
 * @retval  "TRUE = 可能"
 * @retval  "FALSE = "不可"
 */
//--------------------------------------------------------------------------------------------
static u8 ItemChangeCheck( BAG_WORK * wk )
{
  POCKET_DATA * pocket = &wk->dat->p_data[wk->dat->p_now];

//  if( BmpListPosParamGet( wk->lw, pocket->scr+pocket->cur ) == BMPLIST_CANCEL ){
//    return FALSE;
//  }

  if( wk->dat->mode != BAG_MODE_FIELD ){
    return FALSE;
  }

  // きのみとわざマシンは動かせない（常に番号順ソート状態だから）
  if( pocket->type == BAG_POKE_NUTS || pocket->type == BAG_POKE_WAZA ){
    return FALSE;
  }

  return TRUE;
}

//--------------------------------------------------------------------------------------------
/**
 * 入れ替え初期設定
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void ItemChangeInit( BAG_WORK * wk )
{
  POCKET_DATA * pocket = &wk->dat->p_data[wk->dat->p_now];

  wk->irekae_flg   = 1;
  wk->irekae_pos   = pocket->scr + wk->cursor_pos-8;
//  wk->irekae_param = BmpListPosParamGet( wk->lw, wk->irekae_pos );

  BagBmp_ItemChgInfoMsgSet( wk );

//  BmpListRewrite( wk->lw );

  ItemChgCursorChg( wk );

  // どうぐ選択時画面消去
  BagObj_SelectPlateDisappear( wk );
  BagBmp_SelectItemClear( wk );
  BagSelectMenu_Clear( &wk->sub_win[ADD_WIN_SELECT0] );

  // どうぐ選択テキスト消去
  BagBmp_ItemMenu2MoveMenu( wk );

    // BMP表示まわりを元に戻す
    {
      POCKET_DATA *p = &wk->dat->p_data[wk->dat->p_now];
      // 道具入れ替えページに変更
      PageSet( wk, BAG_PAGE_INSERT, _get_page_button_num( wk ), wk->cursor_pos-8 );

      BagBmp_ItemNamePrint( wk, p->scr, wk->cursor_pos-8, ITEMPRINT_INSERT );
      BagBmp_PageNoPrint( wk, p->max, p->scr, 0 );
      BagObj_ItemIconSet( wk, p, _get_page_button_num(wk), 0 );

      // どうぐアイコンと下の上下移動選択を復活させる
      BagObj_ItemMoveIconSet( wk, p,  p->scr+wk->cursor_pos-8 );

    }

    // カーソルの位置を元に戻す
    BgObj_CursorPosAppearSet( wk, wk->cursor_pos );






  // SELECTボタンで移動開始されると危険
  wk->select_cursor_pos = wk->cursor_pos-8;
}


#define MOVE_TABLE_MINUS  ( 8 )

//------------------------------------------------------------------
/**
 * @brief   キー入力でカーソルを移動（どうぐ移動時）
 *
 * @param   pos
 *
 * @retval  int
 */
//------------------------------------------------------------------
static int CursorMove1Step( int pos )
{
  if(sys.trg & PAD_KEY_UP){
    pos = move_cursor_tbl[pos].up-MOVE_TABLE_MINUS;
  }else if(sys.trg & PAD_KEY_DOWN){
    pos = move_cursor_tbl[pos].down-MOVE_TABLE_MINUS;
  }else if(sys.trg & PAD_KEY_LEFT){
    pos = move_cursor_tbl[pos].left-MOVE_TABLE_MINUS;
  }else if(sys.trg & PAD_KEY_RIGHT){
    pos = move_cursor_tbl[pos].right-MOVE_TABLE_MINUS;
  }

  return pos;
}

//------------------------------------------------------------------
/**
 * @brief   どうぐ移動時のカーソル制御
 *
 * @param   pos
 * @param   select
 *
 * @retval  int
 */
//------------------------------------------------------------------
/*
static int ItemMoveCursor( int pos, int select, int top )
{

  pos = CursorMove1Step(pos);

  // ページ内に移動元データが存在している時は移動元にはカーソルが行かないようにする
  if((select/6)*6==top){
    if(pos==(select%6)){
      pos = CursorMove1Step(pos);
    }
  }
  return pos;
}
*/

//------------------------------------------------------------------
/**
 * @brief   どうぐ移動画面中のページ更新
 *
 * @param   wk
 * @param   p
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void item_change_page_refresh( BAG_WORK *wk, POCKET_DATA *p )
{
  PageSet( wk, BAG_PAGE_INSERT, _get_page_button_num(wk),
                    _get_inpage_target(wk) );
  BagBmp_ItemNamePrint( wk, p->scr, _get_inpage_target(wk), ITEMPRINT_INSERT );
  BagObj_ItemMoveIconSet( wk, p, wk->irekae_pos );
  BagBmp_PageNoPrint( wk, wk->dat->p_data[wk->dat->p_now].max,
        wk->dat->p_data[wk->dat->p_now].scr, 0 );

  OS_Printf("scr=%d pos=%d\n", p->scr, wk->cursor_pos-8);

}


//==============================================================================
/**
 * @brief   どうぐ移動時の決定処理
 *
 * @param   wk
 * @param   pos   カーソルの位置（＝タッチの位置）
 *
 * @retval  u32   ボタン毎の処理番号
 */
//==============================================================================
static u32 item_change_decide( BAG_WORK *wk, int pos )
{
  u32 ret=BMPLIST_NULL;;
  switch(pos){
  case 0: case 1: case 2:
  case 3: case 4: case 5:
    if(_get_page_button_num( wk ) > pos){
      ret = wk->select_cursor_pos;
      Snd_SePlay( BAG_SE_ITEM_SELECT );

    }else{
      Snd_SePlay( SEQ_SE_DP_BOX03 );
    }
    break;
  case 6: ret = CURSORPOS_SUBPAGE;      break;
  case 7: ret = CURSORPOS_ADDPAGE;    break;
  case 8: ret = BMPLIST_CANCEL;     break;
  }

  return ret;
}

//--------------------------------------------------------------------------------------------
/**
 * 入れ替え先選択
 *
 * @param wk    バッグ画面のワーク
 *
 * @retval  "TRUE = 終了"
 * @retval  "FALSE = 選択中"
 */
//--------------------------------------------------------------------------------------------
static int ItemChangeMain( BAG_WORK * wk )
{
  POCKET_DATA * pocket;
  u32 ret=BMPLIST_NULL,touch;
  u16 scr, cur;


  pocket = &wk->dat->p_data[wk->dat->p_now];
  cur    = wk->select_cursor_pos;

//  BmpListPosGet( wk->lw, &pocket->scr, &pocket->cur );

/*
  if( sys.trg & PAD_BUTTON_SELECT ){
    Snd_SePlay( BAG_SE_ITEM_SELECT );
    ItemChangeComp( wk );
    return TRUE;
  }
*/

  // 移動元には重ならないキー制御
//  cur = ItemMoveCursor( wk->select_cursor_pos, wk->irekae_pos, pocket->scr );
  cur = CursorMove1Step( wk->select_cursor_pos ); // 移動元と重なってよい。

  if( wk->select_cursor_pos != cur ){
    // ページ切り替えの移動だったら
    if(cur==6 || cur == 7){
      ret = item_change_decide(wk, cur);
    }else{
      // 通常のカーソル移動
      wk->select_cursor_pos = cur;
      BgObj_InsertCursorPosAppearSet( wk, wk->select_cursor_pos );
      Snd_SePlay( BAG_SE_LIST_MOVE1 );
    }
  }

  // 決定
  if((touch=TouchButtonControl( wk, TOUCH_MODE_CHANGE ))!=RECT_HIT_NONE){
    //「やめる」
    if( touch == 8 ){
      ret = item_change_decide( wk, touch );
      BgObj_InsertCursorPosAppearSet( wk, touch );
    // ページ切り替え
    }else if( touch == 6 || touch == 7 ){
      ret = item_change_decide( wk, touch );
    // アイテム
    }else{
      wk->select_cursor_pos = touch;
      if(_get_page_button_num( wk ) > touch){
        ret = item_change_decide( wk, touch );
      }else{
        Snd_SePlay( SEQ_SE_DP_BOX03 );
      }
      BgObj_InsertCursorPosAppearSet( wk, wk->select_cursor_pos );
    }
/*
    if(touch!=6 && touch!=7){
      wk->select_cursor_pos = touch;
      if(_get_page_button_num( wk ) > touch){
        ret = item_change_decide( wk, touch );
      }else{
        Snd_SePlay( SEQ_SE_DP_BOX03 );
        BgObj_InsertCursorPosAppearSet( wk, wk->select_cursor_pos );
      }
    }else{
      ret = item_change_decide( wk, touch );
    }
*/
  }else if(sys.trg & PAD_BUTTON_DECIDE){
    ret = item_change_decide( wk, wk->select_cursor_pos );
  }else if( sys.trg & PAD_BUTTON_CANCEL ){
//    Snd_SePlay( BAG_SE_CLOSE );
    ret = BMPLIST_CANCEL;
  }
//  pocket->scr = scr;
//  pocket->cur = cur;

  switch( ret ){
  case BMPLIST_NULL:
    break;
  case BMPLIST_CANCEL:
//    Snd_SePlay( BAG_SE_ITEM_SELECT );
    Snd_SePlay( BAG_SE_CLOSE );
    pocket->scr = wk->irekae_pos / 6 * 6;
//    ItemChangeEnd( wk );
//    return SEQ_MAIN;
    return ButtonPalAnmSet( wk, ACT_BAG_BACK_BUTTON, 9, 8, SEQ_IREKAE_CANCEL );

  // 左矢印
  case CURSORPOS_SUBPAGE:
/*
    {
      POCKET_DATA *p = &wk->dat->p_data[wk->dat->p_now];
      // どうぐが6個以下ならページ切り替えなし
      if(p->max<=6){
        break;
      }
      // カーソルはループする
      if( p->scr-6 >= 0 ){
        p->scr -= 6;
      }else{
        p->scr = ((p->max-1)/6)*6;
      }
      item_change_page_refresh( wk, p );
      BgObj_InsertCursorPosAppearSet( wk, wk->select_cursor_pos );
      Snd_SePlay( BAG_SE_ITEM_SELECT );
    }
    break;
*/
    if( pocket->max <= 6 ){
      break;
    }
    Snd_SePlay( BAG_SE_ITEM_SELECT );
    return ButtonPalAnmSet( wk, ACT_BAG_UP_BUTTON, 9, 8, SEQ_LIST_SUB );

  // 右矢印
  case CURSORPOS_ADDPAGE:
/*
    {
      POCKET_DATA *p = &wk->dat->p_data[wk->dat->p_now];
      // どうぐが６個以下ならページ切り替えなし
      if(p->max<=6){
        break;
      }
      // カーソルはループする
      if( p->scr+6 < p->max ){
        p->scr += 6;
      }else{
        p->scr = 0;
      }
      item_change_page_refresh( wk, p );
      BgObj_InsertCursorPosAppearSet( wk, wk->select_cursor_pos );
      Snd_SePlay( BAG_SE_ITEM_SELECT );
    }
    break;
*/
    if( pocket->max <= 6 ){
      break;
    }
    Snd_SePlay( BAG_SE_ITEM_SELECT );
    return ButtonPalAnmSet( wk, ACT_BAG_DOWN_BUTTON, 9, 8, SEQ_LIST_ADD );

  default:
    Snd_SePlay( BAG_SE_ITEM_SELECT );
//    ItemChangeComp( wk );
//    return LIST_SEL_ITEM;
//    return SEQ_MAIN;
//    return SEQ_IREKAE_COMP;
    if( wk->irekae_pos == pocket->scr + wk->select_cursor_pos ){
      return ButtonAnmSet( wk, ACT_BAG_CURSOR, 41, SEQ_IREKAE_COMP );
    }
    return ButtonAnmSet( wk, ACT_BAG_CURSOR, 42, SEQ_IREKAE_COMP );
  }

  return SEQ_IREKAE;
}

//--------------------------------------------------------------------------------------------
/**
 * 入れ替え・決定
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static int ItemChangeComp( BAG_WORK * wk )
{
  POCKET_DATA * pocket = &wk->dat->p_data[wk->dat->p_now];
  u16 pos = pocket->scr + wk->select_cursor_pos;

  // 同じ場所でなければどうぐ位置移動
  if( wk->irekae_pos != pos  ){

    ItemPutIn( pocket->item, wk->irekae_pos, pos, wk->dat->p_now, HEAPID_BAG );

    ItemListDataMake( wk );

    // カーソルの位置を移動後の場所に
    wk->cursor_pos = wk->select_cursor_pos+8;
//    pocket->cur = wk->select_cursor_pos;
    _cursor_pos_backup( wk, wk->cursor_pos );
  }

  return ItemChangeEnd( wk );
}

//--------------------------------------------------------------------------------------------
/**
 * 入れ替え・キャンセル
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static int ItemChangeEnd( BAG_WORK * wk )
{
  POCKET_DATA * pocket = &wk->dat->p_data[wk->dat->p_now];

//  BmpListExit( wk->lw, &pocket->scr, &pocket->cur );
  wk->lw = NULL;

//  if( wk->irekae_pos < (pocket->scr+pocket->cur) ){
//    pocket->cur -= 1;
//  }

  wk->irekae_flg   = 0;
  wk->irekae_pos   = 0;
  wk->irekae_param = 0;

//  ItemListSet( wk, pocket->scr, pocket->cur );

  // 移動カーソルの形状変更
  ItemChgCursorChg( wk );

  // カーソルのパレットを変更
//  BagObj_CursorPalChg( wk, 1 );


  // アイテムリスト作成
  ItemListDataMake( wk );

  // BMP表示まわりを元に戻す
  {
    POCKET_DATA *p = &wk->dat->p_data[wk->dat->p_now];
    PageSet( wk, BAG_PAGE_NORMAL, _get_page_button_num(wk), 0 );
    BagBmp_ItemNamePrint( wk, p->scr, -1, ITEMPRINT_NORMAL);
    BgObj_PocketPalSet( wk, wk->dat->p_now );
    BAG_BackGroundPalChange( wk, 1, wk->dat->p_now );
    BagBmp_PageNoPrint( wk, p->max, p->scr, 0 );
    BagObj_ItemIconSet( wk, p, _get_page_button_num(wk), 1 );
  }


  // 1列ウインドウ消去
  BagBmp_MenuInfoClear( wk );

  // カーソルの位置を元に戻す
  BgObj_CursorPosAppearSet( wk, wk->cursor_pos );

  return SEQ_MAIN;
}

//--------------------------------------------------------------------------------------------
/**
 * カーソル切り替え
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void ItemChgCursorChg( BAG_WORK * wk )
{
  POCKET_DATA * pocket = &wk->dat->p_data[wk->dat->p_now];

  if( wk->irekae_flg == 0 ){
/*
    CATS_ObjectPosSetCap(
      wk->cap[ACT_LIST_SEL_CURSOR], CURSOR_ACT_PX, CURSOR_ACT_PY + (pocket->cur-1) * 16 );

    CATS_ObjectEnableCap( wk->cap[ ACT_LIST_SEL_CURSOR ], ACT_ON );
    CATS_ObjectEnableCap( wk->cap[ ACT_LIST_SEL_CHANGE ], ACT_OFF );
    if( wk->p_max != 1 ){
      CATS_ObjectEnableCap( wk->cap[ ACT_POKE_ARROW_LEFT ], ACT_ON );
      CATS_ObjectEnableCap( wk->cap[ ACT_POKE_ARROW_RIGHT ], ACT_ON );
    }
*/
  }else{
    CATS_ObjectPosSetCap(
      wk->cap[ACT_LIST_SEL_CHANGE], CURSOR_ACT_PX, CURSOR_ACT_PY + (pocket->cur-1) * 16 - 8 );

//    CATS_ObjectEnableCap( wk->cap[ ACT_LIST_SEL_CURSOR ], ACT_OFF );
//    CATS_ObjectEnableCap( wk->cap[ ACT_LIST_SEL_CHANGE ], ACT_ON );
//    if( wk->p_max != 1 ){
//      CATS_ObjectEnableCap( wk->cap[ ACT_POKE_ARROW_LEFT ], ACT_OFF );
//      CATS_ObjectEnableCap( wk->cap[ ACT_POKE_ARROW_RIGHT ], ACT_OFF );
//    }
  }
}


//============================================================================================
//============================================================================================
//  メニュー
//============================================================================================
//============================================================================================

//--------------------------------------------------------------------------------------------
/**
 * メニュー作成
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void ItemMenuMake( BAG_WORK * wk )
{
  int  i;
  void * itemdata;
  u8  pocket;
  u8  tbl[BAG_MENUTBL_MAX]={255, 255, 255, 255, 255};

  itemdata = GetItemArcData( wk->dat->ret_item, ITEM_GET_DATA, HEAPID_BAG );
  pocket   = wk->dat->p_data[ wk->dat->p_now ].type;

  for(i=0;i<BAG_MENUTBL_MAX;i++){
    wk->menu_func[i] = NULL;
  }

  // フィールド
  if( wk->dat->mode == BAG_MODE_FIELD ){
    // タグをみる
//    if( pocket == BAG_POKE_NUTS ){
//      tbl[max] = BAG_MENU_TAGUWOMIRU;
//    }
    // コロシアム・ユニオンルームでは「みる」のみ
    if( wk->dat->map_mode == MAP_MODE_COLOSSEUM || wk->dat->map_mode == MAP_MODE_UNION ){
      if( wk->dat->p_data[wk->dat->p_now].type == BAG_POKE_SEAL ){
        tbl[BAG_MENU_USE] = BAG_MENU_MIRU;
      }
    }else{
      // つかう
      // おりる
      // みる
      // ひらく
      // うめる
      // とめる
      if( ItemBufParamGet( itemdata, ITEM_PRM_FIELD ) != 0 ){
        if( wk->dat->ret_item == ITEM_ZITENSYA && wk->dat->cycle_flg == 1 ){
          tbl[BAG_MENU_USE] = BAG_MENU_ORIRU;
        }else if( wk->dat->p_data[wk->dat->p_now].type == BAG_POKE_SEAL ){
          tbl[BAG_MENU_USE] = BAG_MENU_MIRU;
        }else if( wk->dat->ret_item == ITEM_POFINKEESU ){
          tbl[BAG_MENU_USE] = BAG_MENU_HIRAKU;
        }else if( wk->dat->p_data[wk->dat->p_now].type == BAG_POKE_NUTS &&
              ItemUse_KinomiTypeCheck( wk->dat->icwk ) == TRUE ){
          tbl[BAG_MENU_USE] = BAG_MENU_UMERU;
        }else if( wk->dat->ret_item == ITEM_gbPUREIYAA && Snd_GameBoyFlagCheck() == 1 ){
          tbl[BAG_MENU_USE] = BAG_MENU_TOMERU;
        }else{
          tbl[BAG_MENU_USE] = BAG_MENU_TSUKAU;
        }
      }
    }
    // もたせる
    // すてる
    if( ItemBufParamGet( itemdata, ITEM_PRM_EVENT ) == 0 ){
      if( ItemPokeAddCheck( wk->dat->ret_item ) == TRUE ){
        tbl[BAG_MENU_GIVE] = BAG_MENU_MOTASERU;
      }
      if( pocket != BAG_POKE_WAZA ){
        // 技マシンじゃない場合は捨てるを登録
        tbl[BAG_MENU_SUB] = BAG_MENU_SUTERU;
      }
    }
    // とうろく
    // かいじょ
    if( ItemBufParamGet( itemdata, ITEM_PRM_CNV ) != 0 ){
      if( MyItem_CnvButtonItemGet( wk->myitem ) == wk->dat->ret_item
       || MyItem_CnvButton2ItemGet( wk->myitem ) == wk->dat->ret_item ){
        tbl[BAG_MENU_SUB] = BAG_MENU_KAIZYO;
      }else{
        tbl[BAG_MENU_SUB] = BAG_MENU_TOUROKU;
      }
    }
  // 木の実プランター
  }else if( wk->dat->mode == BAG_MODE_N_PLANTER ){
    if( BAGMAIN_NPlanterUseCheck( pocket, wk->dat->ret_item ) == TRUE ){
      tbl[BAG_MENU_USE] = BAG_MENU_TSUKAU_NP;
    }
  }

  // わざマシンときのみでなければどうぐ移動メニューを登録
  if( wk->dat->mode != BAG_MODE_N_PLANTER ){
    if(pocket!=BAG_POKE_WAZA && pocket!=BAG_POKE_NUTS){
      tbl[BAG_MENU_ITEMMOVE] = BAG_MENU_IDOU;
    }
  }
  // やめる
  tbl[BAG_MENU_CANCEL] = BAG_MENU_YAMERU;

  OS_Printf("pocket=%d\n",   pocket);
  OS_Printf("tbl[BAG_MENU_USE]=%d\n",   tbl[BAG_MENU_USE]);
  OS_Printf("tbl[BAG_MENU_GIVE]=%d\n",  tbl[BAG_MENU_GIVE]);
  OS_Printf("tbl[BAG_MENU_SUB]=%d\n",   tbl[BAG_MENU_SUB]);
  OS_Printf("tbl[BAG_MENU_MOVE]=%d\n",   tbl[BAG_MENU_ITEMMOVE]);
//  OS_Printf("tbl[BAG_MENU_CANCEL]=%d\n",tbl[BAG_MENU_CANCEL]);

  for(i=0;i<BAG_MENUTBL_MAX;i++){
    if(tbl[i]!=255){
      wk->menu_func[i] = MenuFuncTbl[tbl[i]];
    }
    OS_Printf("menu_func[%d]=%08x\n", i,wk->menu_func[i]);
  }

  // メニュー作成
  Bag_ItemMenuSet( wk, tbl, 5 );
  // 選択メニューの初期化
  SelectMenuInit(wk, tbl);

  sys_FreeMemoryEz( itemdata );
}


//------------------------------------------------------------------
/**
 * @brief   選択メニューの初期化
 *
 * @param   wk    バッグ画面ワーク
 * @param   tbl   メニューテーブル
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void SelectMenuInit( BAG_WORK *wk, u8 *tbl )
{
  // カーソルの初期化
  wk->select_cursor_pos = 0;
  BgObj_CursorPosAppearSet( wk, select_cursor_pos_tbl[wk->select_cursor_pos] );

  BagObj_SelectPlateAppear( wk, tbl );


  BagSelectMenu_StringPrint( &wk->sub_win[ADD_WIN_SELECT0], wk->menu_str, tbl[0] );
  BagSelectMenu_StringPrint( &wk->sub_win[ADD_WIN_SELECT1], wk->menu_str, tbl[1] );
  BagSelectMenu_StringPrint( &wk->sub_win[ADD_WIN_SELECT2], wk->menu_str, tbl[2] );
  BagSelectMenu_StringPrint( &wk->sub_win[ADD_WIN_SELECT3], wk->menu_str, tbl[3] );

}

//------------------------------------------------------------------
/**
 * @brief   アイテム選択後メニューのカーソル移動
 *
 * @param   wk    バッグ画面ワーク
 *
 * @retval  u32
 */
//------------------------------------------------------------------
static u32 CursorMenuMain( BAG_WORK *wk )
{
  u32 pos = wk->select_cursor_pos;
  int touch;

  // 移動
  if(sys.trg & PAD_KEY_UP){
    pos = select_cursor_tbl[pos].up;
  }else if(sys.trg & PAD_KEY_DOWN){
    pos = select_cursor_tbl[pos].down;
  }else if(sys.trg & PAD_KEY_LEFT){
    pos = select_cursor_tbl[pos].left;
  }else if(sys.trg & PAD_KEY_RIGHT){
    pos = select_cursor_tbl[pos].right;
  }

  // カーソルが移動していたら反映
  if(pos!=wk->select_cursor_pos){
    wk->select_cursor_pos = pos;
    BgObj_CursorPosAppearSet( wk, select_cursor_pos_tbl[pos] );

    OS_Printf("pos = %d, pos_tbl = %d\n,", pos, select_cursor_pos_tbl[pos]);
    Snd_SePlay( BAG_SE_LIST_MOVE1 );
    return BMPMENU_NULL;
  }

  if((touch=TouchButtonControl( wk, TOUCH_MODE_SELECT ))!=RECT_HIT_NONE){
    pos = touch;
    _set_keytouch_status(wk, APP_END_TOUCH);
    wk->select_cursor_pos = touch;
    BgObj_CursorPosAppearSet( wk, select_cursor_pos_tbl[pos] );

    if(pos==4){
      Snd_SePlay( BAG_SE_CLOSE );
      return BMPMENU_CANCEL;
    }else{
      if(wk->menu_func[pos]!=NULL){
        Snd_SePlay( BAG_SE_ITEM_SELECT );
        return pos;
      }
    }
  }else if(sys.trg & PAD_BUTTON_DECIDE){
    if(wk->menu_func[pos]!=NULL){
      Snd_SePlay( BAG_SE_ITEM_SELECT );
      _set_keytouch_status(wk, APP_END_KEY );
      return pos;
    }
    if(pos==4){
      Snd_SePlay( BAG_SE_ITEM_SELECT );
      return BMPMENU_CANCEL;
    }
  }else if(sys.trg&PAD_BUTTON_CANCEL){
    Snd_SePlay( BAG_SE_CLOSE );
    return BMPMENU_CANCEL;
  }

  return BMPMENU_NULL;
}

//------------------------------------------------------------------
/**
 * @brief   どうぐ選択セレクトメニューを元に戻す
 *
 * @param   wk    バッグ画面ワーク
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void select_menu_cancel( BAG_WORK *wk )
{
  // アイテムリスト作成
  ItemListDataMake( wk );

  // BMP表示まわりを元に戻す
  {
    POCKET_DATA *p = &wk->dat->p_data[wk->dat->p_now];
    PageSet( wk, BAG_PAGE_NORMAL, _get_page_button_num(wk), 0 );
    BagBmp_ItemNamePrint( wk, p->scr, -1, ITEMPRINT_NORMAL);
    BgObj_PocketPalSet( wk, wk->dat->p_now );
    BAG_BackGroundPalChange( wk, 1, wk->dat->p_now );
    BagBmp_PageNoPrint( wk, p->max, p->scr, 0 );
    BagObj_ItemIconSet( wk, p, _get_page_button_num(wk), 0 );
  }

  // カーソルの位置を元に戻す
  BgObj_CursorPosAppearSet( wk, wk->cursor_pos );

  // 技マシン用にスクロールしたＢＧを戻す
  BAGMAIN_InfoWinLoad( wk, TRUE );
}


//--------------------------------------------------------------------------------------------
/**
 * メニューコントロール
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int MenuControl( BAG_WORK * wk )
{
  u32 ret=BMPMENU_NULL;

//  ret = BmpMenuMain( wk->mw );

  ret = CursorMenuMain( wk );

  switch( ret ){
  case BMPMENU_NULL:
    break;

  case BMPMENU_CANCEL:
    return ButtonPalAnmSet( wk, ACT_BAG_BACK_BUTTON, 9, 8, SEQ_MENU_CANCEL );

  default:
    wk->sel_menu = ret;
    return ButtonPalAnmSet( wk, ACT_BAG_SELECT_PLATE0+ret, 9, 8, SEQ_MENU_SELECT );
  }

  return SEQ_MENU;
}

//--------------------------------------------------------------------------------------------
/**
 * メニューキャンセル処理
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int SeqMenuCancel( BAG_WORK * wk )
{
  // 選択肢隠す
  BagObj_SelectPlateDisappear( wk );
  BagBmp_SelectItemClear( wk );
  BagSelectMenu_Clear( &wk->sub_win[ADD_WIN_SELECT0] );
  BagObj_ItemIconSet( wk, &wk->dat->p_data[wk->dat->p_now], _get_page_button_num(wk), 0 );
  BagBmp_WazaInfoClear(wk);

  Bag_ItemMenuExit( wk );

  // メニュー画面を元に戻す
  select_menu_cancel(wk);

  return SEQ_MAIN;
}

//--------------------------------------------------------------------------------------------
/**
 * メニュー決定処理
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int SeqMenuSelect( BAG_WORK * wk )
{
  // 選択肢隠す
  BagObj_SelectPlateDisappear( wk );
  BagSelectMenu_Clear( &wk->sub_win[ADD_WIN_SELECT0] );

  return wk->menu_func[wk->sel_menu](wk);
}


//============================================================================================
//  メニュー：つかう
//============================================================================================

//--------------------------------------------------------------------------------------------
/**
 * メニュー：つかう
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int Bag_MenuUse( BAG_WORK * wk )
{
  ITEMCHECK_FUNC  check;
  s32 id;

  // どうぐ使用メニュー描画状態解放
//  Bag_ItemMenuExit( wk );

  BackButtonOnOffChange( wk, FALSE );
  BagObj_CursorDisappear( wk );

  // どうぐ使用処理取得
  id    = ItemParamGet( wk->dat->ret_item, ITEM_PRM_FIELD, HEAPID_BAG );
  check = (ITEMCHECK_FUNC)ItemUse_FuncGet( ITEMUSE_PRM_CHECKFUNC, id );

  // どうぐ使用チェック
  if( check != NULL ){
    u32 ret = check( wk->dat->icwk );
    if( ret != ITEMCHECK_TRUE ){
      BAG_ItemUseErrorMsgSet( wk->myst, wk->expb, wk->dat->ret_item, ret, HEAPID_BAG );
      wk->midx = Bag_TalkMsgPrint( wk, BAG_TALK_FULL );
      return SEQ_ITEM_ERR_WAIT;
    }
  }

  return BAG_ItemUse( wk );
}

//--------------------------------------------------------------------------------------------
/**
 * エラーメッセージ表示
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  次のシーケンス
 */
//--------------------------------------------------------------------------------------------
static int ItemErrWaitSeq( BAG_WORK * wk )
{
  if( GF_MSG_PrintEndCheck( wk->midx ) == 0 ){
    if( (sys.trg & (PAD_BUTTON_DECIDE|PAD_BUTTON_CANCEL)) || sys.tp_trg ){
      if( wk->dat->mode != BAG_MODE_KINOMI ){
        Bag_ItemMenuExit( wk );
      }
      BmpTalkWinClear( &wk->win[WIN_TALK], WINDOW_TRANS_OFF );
      GF_BGL_BmpWinOffVReq( &wk->win[WIN_TALK] );
      GF_BGL_BmpWinOnVReq( &wk->win[WIN_INFO] );
      BackButtonOnOffChange( wk, TRUE );
      select_menu_cancel(wk);
      if( wk->dat->mode == BAG_MODE_KINOMI ){
        return SEQ_KINOMISEL_MAIN;
      }else{
        return SEQ_MAIN;
      }
    }
  }
  return SEQ_ITEM_ERR_WAIT;
}

//--------------------------------------------------------------------------------------------
/**
 * バッグ内アイテム使用
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  次のシーケンス
 */
//--------------------------------------------------------------------------------------------
static int BAG_ItemUse( BAG_WORK * wk )
{
  POCKET_DATA * pocket = &wk->dat->p_data[wk->dat->p_now];

  wk->sub_seq  = 0;

  // 技マシン
  if( pocket->type == BAG_POKE_WAZA ){
    wk->use_func = (u32)BAG_ItemUseWazaMachine;
    return SEQ_BAG_ITEMUSE;
  }

  // コインケース、シール入れ、アクセサリー入れ、ポイントカード
  if( BAG_ItemUseMsgSet( wk->dat->sv, wk->expb, wk->dat->ret_item, HEAPID_BAG ) == TRUE ){
    wk->midx = Bag_TalkMsgPrint( wk, BAG_TALK_FULL );
    return SEQ_ITEM_ERR_WAIT;
  }

  // 白黒ビードロ、スプレー
  if( BAG_ItemUseMsgNormal( wk, wk->dat->ret_item ) == TRUE ){
    wk->use_func = (u32)BAG_ItemUseMsgNormalFunc;
    return SEQ_BAG_ITEMUSE;
  }

  APP_WipeStart( APP_WIPE_OUT, HEAPID_BAG );
  wk->dat->ret_mode = BAG_RET_USE;  // 終了モード
  return SEQ_OUT;
}

//--------------------------------------------------------------------------------------------
/**
 * アイテム使用（通常）
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  アイテム処理の戻り値
 */
//--------------------------------------------------------------------------------------------
static int Seq_BagItemUse( BAG_WORK * wk )
{
  seqFunc func = (seqFunc)wk->use_func;
  return  func(wk);
}

//--------------------------------------------------------------------------------------------
/**
 * 技マシン使用
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  次のシーケンス
 */
//--------------------------------------------------------------------------------------------
static int BAG_ItemUseWazaMachine( BAG_WORK * wk )
{
  switch( wk->sub_seq ){

  // 技マシンをきどうした！
  case 0:
    {
      u16 waza = GetWazaNoItem( wk->dat->ret_item );
      WORDSET_RegisterWazaName( wk->wset, 0, waza );
      if( HidenWazaCheck( waza ) == TRUE ){
        MSGMAN_GetString( wk->msg_man, msg_bag_064, wk->expb );
      }else{
        MSGMAN_GetString( wk->msg_man, msg_bag_063, wk->expb );
      }
    }
    wk->midx    = Bag_TalkMsgPrint( wk, BAG_TALK_FULL );
    wk->sub_seq = 1;
    break;

  // ●●を□□におぼえさせますか？
  case 1:
    if( GF_MSG_PrintEndCheck( wk->midx ) != 0 ){ break; }
    if( (sys.trg & (PAD_BUTTON_DECIDE|PAD_BUTTON_CANCEL)) || sys.tp_trg ){
      STRBUF * str = MSGMAN_AllocString( wk->msg_man, msg_bag_065 );
      GF_BGL_BmpWinDataFill( &wk->win[WIN_TALK], 15 );
      WORDSET_ExpandStr( wk->wset, wk->expb, str );
      STRBUF_Delete( str );
      wk->midx    = Bag_TalkMsgPrint( wk, BAG_TALK_FULL );
      wk->sub_seq = 2;
    }
    break;

  case 2:
    if( GF_MSG_PrintEndCheck( wk->midx ) != 0 ){ break; }
    Bag_YesNoSelInit( wk );
    wk->sub_seq = 3;
    break;

  // はい・いいえ待ち
  case 3:
    {
      u32 ret;

      ret = TOUCH_SW_Main( wk->tss );

      switch( ret ){
      case TOUCH_SW_RET_YES:
        Bag_YesNoSelEnd( wk );
        APP_WipeStart( APP_WIPE_OUT, HEAPID_BAG );
        wk->dat->ret_mode = BAG_RET_USE;  // 終了モード
        return SEQ_OUT;

      case TOUCH_SW_RET_NO:
        Bag_YesNoSelEnd( wk );
        Bag_ItemMenuExit( wk );
        BmpTalkWinClear( &wk->win[WIN_TALK], WINDOW_TRANS_OFF );
        GF_BGL_BmpWinOffVReq( &wk->win[WIN_TALK] );
        GF_BGL_BmpWinOnVReq( &wk->win[WIN_INFO] );
        BagObj_ItemIconSet( wk, &wk->dat->p_data[wk->dat->p_now], _get_page_button_num(wk), 0 );
        BagBmp_WazaInfoClear(wk);
        BagObj_SelectPlateDisappear( wk );

        // メニュー画面を元に戻す
        select_menu_cancel(wk);

        BackButtonOnOffChange( wk, TRUE );

        return SEQ_MAIN;
      default:
        break;
      }
    }
    break;
  }
  return SEQ_BAG_ITEMUSE;
}

//--------------------------------------------------------------------------------------------
/**
 * 白黒ビードロ、スプレー
 *
 * @param wk    バッグ画面ワーク
 * @param item  アイテム番号
 *
 * @retval  "TURE = 使用"
 * @retval  "FALSE = 白黒ビードロ、スプレー以外"
 */
//--------------------------------------------------------------------------------------------
static BOOL BAG_ItemUseMsgNormal( BAG_WORK * wk, u16 item )
{
  STRBUF * str;

  WORDSET_RegisterPlayerName( wk->wset, 0, wk->myst );
  WORDSET_RegisterItemName( wk->wset, 1, item );

  if( item == ITEM_KUROIBIIDORO ){
    str = MSGMAN_AllocString( wk->msg_man, msg_bag_069 );
    BAG_SaveDataVidroSet( wk, VIDRO_BLACK );
    wk->sel_num = 0;
  }else if( item == ITEM_SIROIBIIDORO ){
    str = MSGMAN_AllocString( wk->msg_man, msg_bag_068 );
    BAG_SaveDataVidroSet( wk, VIDRO_WHITE );
    wk->sel_num = 0;
  }else if( item == ITEM_GOORUDOSUPUREE || item == ITEM_SIRUBAASUPUREE || item == ITEM_MUSIYOKESUPUREE ){
    str = BAG_SpraySet( wk, item );
  }else if( item == ITEM_gbPUREIYAA ){
    str = BAG_GameboySet( wk, item );
    wk->sel_num = 0;
  }else{
    return FALSE;
  }

  WORDSET_ExpandStr( wk->wset, wk->expb, str );
  STRBUF_Delete( str );

  return TRUE;
}

//--------------------------------------------------------------------------------------------
/**
 * スプレーセット
 *
 * @param wk    バッグ画面ワーク
 * @param item  アイテム番号
 *
 * @return  取得メッセージ
 */
//--------------------------------------------------------------------------------------------
static STRBUF * BAG_SpraySet( BAG_WORK * wk, u16 item )
{
  s32 prm;
  u8 * swk;

  // スプレー効果チェック
  if( EncDataSave_CanUseSpray( BAG_EncountSaveGet(wk) ) == FALSE ){
    wk->sel_num = 0;
    return MSGMAN_AllocString( wk->msg_man, msg_bag_067 );
  }

  prm = ItemParamGet( item, ITEM_PRM_ATTACK, HEAPID_BAG );
  BAG_SaveDataSpraySet( wk, (u8)prm );
  wk->sel_num = 1;
  Snd_SePlay( SEQ_SE_DP_CARD2 );
  return MSGMAN_AllocString( wk->msg_man, msg_bag_066 );
}

//--------------------------------------------------------------------------------------------
/**
 * ゲームボーイセット
 *
 * @param wk    バッグ画面ワーク
 * @param item  アイテム番号
 *
 * @return  取得メッセージ
 */
//--------------------------------------------------------------------------------------------
static STRBUF * BAG_GameboySet( BAG_WORK * wk, u16 item )
{
  // ゲームボーイフラグチェック
  if( Snd_GameBoyFlagCheck() == TRUE){
    Snd_GameBoyItemUse();
    return MSGMAN_AllocString( wk->msg_man, mes_bag_111 );
  }

  Snd_GameBoyItemUse();
//  Snd_SePlay( SEQ_SE_DP_CARD2 );
  return MSGMAN_AllocString( wk->msg_man, mes_bag_110 );
}


//--------------------------------------------------------------------------------------------
/**
 * アイテムを減らしてリストを再設定
 *
 * @param wk    バッグ画面ワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void BAG_ItemSubListReset( BAG_WORK * wk )
{
  MyItem_SubItemDirect(
    wk->dat->p_data[wk->dat->p_now].item,
    wk->dat->p_data[ wk->dat->p_now ].max,
    wk->dat->ret_item, wk->sel_num, HEAPID_BAG );

  ItemListDataMake( wk );

  ItemListParamReset(
    &wk->dat->p_data[wk->dat->p_now].scr,
    &wk->dat->p_data[wk->dat->p_now].cur,
    wk->dat->p_data[wk->dat->p_now].max );
  ItemListCurPosReset(
    &wk->dat->p_data[wk->dat->p_now].scr,
    &wk->dat->p_data[wk->dat->p_now].cur,
    wk->dat->p_data[wk->dat->p_now].max, ONE_PAGE_LIST_MAX );
}

//--------------------------------------------------------------------------------------------
/**
 * 使用メッセージ処理
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  次のシーケンス
 */
//--------------------------------------------------------------------------------------------
static int BAG_ItemUseMsgNormalFunc( BAG_WORK * wk )
{
  switch( wk->sub_seq ){
  case 0:   // メッセージ描画
    wk->midx = Bag_TalkMsgPrint( wk, BAG_TALK_FULL );
    wk->sub_seq = 1;
    break;

  case 1:
    if( GF_MSG_PrintEndCheck( wk->midx ) != 0 ){ break; }
    if( (sys.trg & (PAD_BUTTON_DECIDE|PAD_BUTTON_CANCEL)) || sys.tp_trg ){
      Bag_ItemMenuExit( wk );
      BmpTalkWinClear( &wk->win[WIN_TALK], WINDOW_TRANS_OFF );
      GF_BGL_BmpWinOffVReq( &wk->win[WIN_TALK] );
      BAG_ItemSubListReset( wk );
      select_menu_cancel(wk);
      // リスト再描画
      BagObj_ItemIconSet( wk, &wk->dat->p_data[wk->dat->p_now], _get_page_button_num(wk), 1 );
      // 説明再描画
      _item_explain_put( wk );
      GF_BGL_BmpWinOnVReq( &wk->win[WIN_INFO] );
      BackButtonOnOffChange( wk, TRUE );
      wk->sub_seq = 0;
      return SEQ_MAIN;
    }
    break;
  }
  return SEQ_BAG_ITEMUSE;
}


//============================================================================================
//  メニュー：タグをみる
//============================================================================================

//--------------------------------------------------------------------------------------------
/**
 * メニュー：タグをみる
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int Bag_MenuTag( BAG_WORK * wk )
{
  Bag_ItemMenuExit( wk );

  APP_WipeStart( APP_WIPE_OUT, HEAPID_BAG );
  wk->dat->ret_mode = BAG_RET_TAG;  // 終了モード
  return SEQ_OUT;
}


//============================================================================================
//  メニュー：けってい
//============================================================================================

//--------------------------------------------------------------------------------------------
/**
 * メニュー：けってい
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int Bag_MenuKettei( BAG_WORK * wk )
{
  Bag_ItemMenuExit( wk );

  APP_WipeStart( APP_WIPE_OUT, HEAPID_BAG );
  wk->dat->ret_mode = BAG_RET_ENTER;  // 終了モード
  return SEQ_OUT;
}


//============================================================================================
//  メニュー：すてる
//============================================================================================

//--------------------------------------------------------------------------------------------
/**
 * 捨てる初期化
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int Bag_MenuSub( BAG_WORK * wk )
{
  wk->sel_num = 1;

  // カーソル隠す
  BagObj_CursorDisappear( wk );

  // 指定のどうぐが１つしかないか確認（１つの場合はすぐにはい・いいえへ）
  if( MyItem_GetItemNumDirect(
      wk->dat->p_data[wk->dat->p_now].item,
      wk->dat->p_data[wk->dat->p_now].max, wk->dat->ret_item, HEAPID_BAG ) == 1 ){

    Bag_SubTalkWinSet( wk );
    BackButtonOnOffChange( wk, FALSE );
    return SEQ_ITEM_SUB_YN_INIT;
  }

  // 捨てる個数指定へ
  PageSet( wk, BAG_PAGE_SUB, 0, 0 );

  // 数字選択用ボタン表示
  BagObj_SelectCountAppear( wk, NUM_DIGIT_3, wk->sel_max );

  // 数字描画
  Bag_SubNumPut( wk, NUM_DIGIT_3 );

  // 「すてる」描画
  BagBmp_DepositPrint( wk );
  BagBmp_CancelPrint( wk, 1 );

  return SEQ_ITEM_SUB_MAIN;
}


//------------------------------------------------------------------
/**
 * @brief   どうぐの数と最大数の範囲で数を増減させる
 *
 * @param   num   現在の数
 * @param   max   最大数
 * @param   move  変動させる数（-100〜100）
 *
 * @retval  static
 */
//------------------------------------------------------------------
static int ItemNumMove( int num, int max, int move )
{
  if(move>0){
    // プラスのとき
    if(num==max){
      num = 1;
    }else{
      num += move;
      if(num>max){
        num = max;
      }
    }
  }else{
    // マイナスのとき
    if(num==1){
      num = max;
    }else{
      num += move;
      if(num<=0){
        num = 1;
      }
    }
  }

  return num;
}

//--------------------------------------------------------------------------------------------
/**
 * 捨てる個数選択
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int Bag_MenuSubMain( BAG_WORK * wk )
{
  u32 touch,ret=APP_NUMSEL_NONE;

  if((touch=TouchButtonControl( wk, TOUCH_MODE_NUMBER ))!=RECT_HIT_NONE){
    switch(Bag_GetCountButtonPassive( wk->sel_max )){
    case 1:
      if(touch==0 || touch==3){
        touch = -1;
      }
      break;
    case 2:
      if(touch==0 || touch==1 || touch==3 || touch==4){
        touch = -1;
      }
      break;
    }

    switch(touch){
    case 0:
      wk->sel_num = ItemNumMove( wk->sel_num, wk->sel_max, 100 );
      CATS_ObjectAnimeFrameSetCap( wk->cap[ACT_BAG_NUM_UP0], 0 );
      CATS_ObjectAnimeSeqSetCap( wk->cap[ACT_BAG_NUM_UP0], 26 );
      ret = APP_NUMSEL_UP;
      break;
    case 1:
      wk->sel_num = ItemNumMove( wk->sel_num, wk->sel_max, 10 );
      CATS_ObjectAnimeFrameSetCap( wk->cap[ACT_BAG_NUM_UP1], 0 );
      CATS_ObjectAnimeSeqSetCap( wk->cap[ACT_BAG_NUM_UP1], 26 );
      ret = APP_NUMSEL_UP;
      break;
    case 2:
      wk->sel_num = ItemNumMove( wk->sel_num, wk->sel_max, 1 );
      CATS_ObjectAnimeFrameSetCap( wk->cap[ACT_BAG_NUM_UP2], 0 );
      CATS_ObjectAnimeSeqSetCap( wk->cap[ACT_BAG_NUM_UP2], 26 );
      ret = APP_NUMSEL_UP;
      break;
    case 3:
      wk->sel_num = ItemNumMove( wk->sel_num, wk->sel_max, -100 );
      CATS_ObjectAnimeFrameSetCap( wk->cap[ACT_BAG_NUM_DOWN0], 0 );
      CATS_ObjectAnimeSeqSetCap( wk->cap[ACT_BAG_NUM_DOWN0], 28 );
      ret = APP_NUMSEL_DOWN;
      break;
    case 4:
      wk->sel_num = ItemNumMove( wk->sel_num, wk->sel_max, -10 );
      CATS_ObjectAnimeFrameSetCap( wk->cap[ACT_BAG_NUM_DOWN1], 0 );
      CATS_ObjectAnimeSeqSetCap( wk->cap[ACT_BAG_NUM_DOWN1], 28 );
      ret = APP_NUMSEL_DOWN;
      break;
    case 5:
      wk->sel_num = ItemNumMove( wk->sel_num, wk->sel_max, -1 );
      CATS_ObjectAnimeFrameSetCap( wk->cap[ACT_BAG_NUM_DOWN2], 0 );
      CATS_ObjectAnimeSeqSetCap( wk->cap[ACT_BAG_NUM_DOWN2], 28 );
      ret = APP_NUMSEL_DOWN;
      break;
    case 6:
      ret = APP_NUMSEL_DECIDE;
      break;
    case 7:
      ret = APP_NUMSEL_CANCEL;
      break;
    }
  }else{
    ret=NumSelectCheck( &wk->sel_num, wk->sel_max );
    if(ret==APP_NUMSEL_NONE){
      if( sys.trg & PAD_BUTTON_DECIDE ){
        ret = APP_NUMSEL_DECIDE;
      }else if( sys.trg & PAD_BUTTON_CANCEL ){
        ret = APP_NUMSEL_CANCEL;
      }
    }
  }

  // 入力毎に
  switch( ret ){
  case APP_NUMSEL_NONE:
    break;
  // 数値変更
  case APP_NUMSEL_UP:
  case APP_NUMSEL_DOWN:
    Bag_SubNumPut( wk, NUM_DIGIT_3 );
    Snd_SePlay( SEQ_SE_DP_BAG_004 );
    return SEQ_ITEM_SUB_MAIN;
  // 決定
  case APP_NUMSEL_DECIDE:
    Snd_SePlay( BAG_SE_ITEM_SELECT );
    return ButtonPalAnmSet( wk, ACT_BAG_BUTTON_SELL_DOPOSIT, 9, 8, SEQ_ITEM_SUB_ENTER );

  // キャンセル
  case APP_NUMSEL_CANCEL:
    Snd_SePlay( BAG_SE_CLOSE );
    return ButtonPalAnmSet( wk, ACT_BAG_BACK_BUTTON, 9, 8, SEQ_ITEM_SUB_CANCEL );
  }

  return SEQ_ITEM_SUB_MAIN;
}

//--------------------------------------------------------------------------------------------
/**
 * 捨てる個数決定
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int Bag_MenuSubNumEnter( BAG_WORK * wk )
{
  Bag_SubTalkWinSet( wk );
  BagObj_SelectCountDisappear( wk );
  BagObj_CursorDisappear( wk );
  BagBmp_DepositSaleClear( wk );
  BackButtonOnOffChange( wk, FALSE );
  return SEQ_ITEM_SUB_YN_INIT;
}

//--------------------------------------------------------------------------------------------
/**
 * 捨てる選択キャンセル
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int Bag_MenuSubNumCancel( BAG_WORK * wk )
{
  Bag_ItemMenuExit( wk );
  select_menu_cancel( wk );
  BagObj_SelectCountDisappear( wk );
  BagBmp_CancelPrint( wk, 0 );
  CATS_ObjectAnimeFrameSetCap( wk->cap[ACT_BAG_BACK_BUTTON], 0 );
  CATS_ObjectAnimeSeqSetCap( wk->cap[ACT_BAG_BACK_BUTTON], 16 );
  return SEQ_MAIN;
}

//--------------------------------------------------------------------------------------------
/**
 * 「すてる」はい・いいえ初期化
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int Bag_MenuSubYesNoInitSeq( BAG_WORK * wk )
{
  if( GF_MSG_PrintEndCheck( wk->midx ) == 0 ){
    Bag_YesNoSelInit( wk );
    return SEQ_ITEM_SUB_YN_SEL;
  }
  return SEQ_ITEM_SUB_YN_INIT;
}

//--------------------------------------------------------------------------------------------
/**
 * 「すてる」はい・いいえ
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int Bag_MenuSubYesNoSelectSeq( BAG_WORK * wk )
{
  u32 ret;


  // はい・いいえメイン処理
  ret = TOUCH_SW_Main( wk->tss );

  switch( ret ){
  // はい
  case TOUCH_SW_RET_YES:
    Bag_YesNoSelEnd( wk );
    {
      STRBUF * str = MSGMAN_AllocString( wk->msg_man, msg_bag_055 );
      WORDSET_RegisterItemName( wk->wset, 0, wk->dat->ret_item );
      WORDSET_RegisterNumber(
        wk->wset, 1, wk->sel_num, 3, NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_DEFAULT );
      WORDSET_ExpandStr( wk->wset, wk->expb, str );
      STRBUF_Delete( str );
    }
    GF_BGL_BmpWinDataFill( &wk->win[WIN_TALK], 15 );
    wk->midx = Bag_TalkMsgPrint( wk, BAG_TALK_FULL );
    return SEQ_ITEM_SUB_CMP;

  case BMPMENU_NULL:
    break;

  // いいえ
  case TOUCH_SW_RET_NO:
    Bag_YesNoSelEnd( wk );
    BmpTalkWinClear( &wk->win[WIN_TALK], WINDOW_TRANS_OFF );
    GF_BGL_BmpWinOffVReq( &wk->win[WIN_TALK] );
    GF_BGL_BmpWinOnVReq( &wk->win[WIN_INFO] );

    BagObj_ItemIconSet( wk, &wk->dat->p_data[wk->dat->p_now], _get_page_button_num(wk), 0 );
    BagBmp_WazaInfoClear(wk);
    Bag_ItemMenuExit( wk );
    BackButtonOnOffChange( wk, TRUE );

    // メニュー画面を元に戻す
    select_menu_cancel(wk);

    return SEQ_MAIN;
  }
  return SEQ_ITEM_SUB_YN_SEL;
}

//--------------------------------------------------------------------------------------------
/**
 * 「すてる」完了
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int Bag_MenuSubCmpSeq( BAG_WORK * wk )
{
  if( GF_MSG_PrintEndCheck( wk->midx ) != 0 ){
    return SEQ_ITEM_SUB_CMP;
  }
  GF_BGL_BmpWinOnVReq( &wk->win[WIN_TALK] );

  return SEQ_ITEM_SUB_RET;
}

//--------------------------------------------------------------------------------------------
/**
 * 「すてる」メッセージ終了待ち＆ボタン待ち -> メインへ
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int Bag_MenuSubRetSeq( BAG_WORK * wk )
{
  if( GF_MSG_PrintEndCheck( wk->midx ) == 0 ){
    if( ( sys.trg & (PAD_BUTTON_DECIDE|PAD_BUTTON_CANCEL) ) || sys.tp_trg ){
      BmpTalkWinClear( &wk->win[WIN_TALK], WINDOW_TRANS_OFF );
      GF_BGL_BmpWinOffVReq( &wk->win[WIN_TALK] );
      GF_BGL_BmpWinOnVReq( &wk->win[WIN_INFO] );

      // どうぐの削除＆リスト再構築
      MyItem_SubItemDirect(
        wk->dat->p_data[wk->dat->p_now].item,
        wk->dat->p_data[ wk->dat->p_now ].max,
        wk->dat->ret_item, wk->sel_num, HEAPID_BAG );
      ItemListDataMake( wk );

      // リスト再描画
      BagObj_ItemIconSet( wk, &wk->dat->p_data[wk->dat->p_now], _get_page_button_num(wk), 1 );

      BagBmp_WazaInfoClear(wk);
      Bag_ItemMenuExit( wk );

      // メニュー画面を元に戻す
      select_menu_cancel(wk);
      // 説明再描画
      _item_explain_put( wk );

      BackButtonOnOffChange( wk, TRUE );

      return SEQ_MAIN;
    }
  }
  return SEQ_ITEM_SUB_RET;
}


//============================================================================================
//  メニュー：とうろく
//============================================================================================

//--------------------------------------------------------------------------------------------
/**
 * メニュー：とうろく
 *
 * @param wk    バッグ画面ワーク
 *
 * @return  次のシーケンス
 */
//--------------------------------------------------------------------------------------------
static int Bag_MenuCnvSet( BAG_WORK * wk )
{
  // 便利ボタン登録

  if(MyItem_CnvButtonItemSet( wk->myitem, wk->dat->ret_item )==0){
    // 一杯だったらエラー
    STRBUF * str = MSGMAN_AllocString( wk->msg_man, mes_bag_109 );
    GF_BGL_BmpWinDataFill( &wk->win[WIN_TALK], 15 );
    WORDSET_ExpandStr( wk->wset, wk->expb, str );
    STRBUF_Delete( str );

    Bag_TalkMsgPrint( wk, BAG_TALK_FULL );
    BagObj_SelectPlateDisappear( wk );
    BagObj_CursorDisappear( wk );
    BackButtonOnOffChange( wk, FALSE );
    return SEQ_ITEM_REGIST_ERR;
  }

  // 登録成功
  BagObj_SelectPlateDisappear( wk );
  BagBmp_SelectItemClear( wk );
  BagSelectMenu_Clear( &wk->sub_win[ADD_WIN_SELECT0] );
  BagObj_ItemIconSet( wk, &wk->dat->p_data[wk->dat->p_now], _get_page_button_num(wk), 0 );
  BagBmp_WazaInfoClear(wk);

  Bag_ItemMenuExit( wk );

  // メニュー画面を元に戻す
  select_menu_cancel(wk);

  return SEQ_MAIN;
}


//------------------------------------------------------------------
/**
 * @brief   登録に失敗
 *
 * @param wk    バッグ画面ワーク
 *
 * @retval  int
 */
//------------------------------------------------------------------
static int Bag_MenuCnvErr( BAG_WORK *wk )
{
  // 登録成功

  if( GF_MSG_PrintEndCheck( wk->midx ) == 0 ){
    if( ( sys.trg & (PAD_BUTTON_DECIDE|PAD_BUTTON_CANCEL) ) || sys.tp_trg ){
      BmpTalkWinClear( &wk->win[WIN_TALK], WINDOW_TRANS_OFF );
      GF_BGL_BmpWinOffVReq( &wk->win[WIN_TALK] );
      BagObj_SelectPlateDisappear( wk );
      BagBmp_SelectItemClear( wk );
      BagSelectMenu_Clear( &wk->sub_win[ADD_WIN_SELECT0] );
      BagObj_ItemIconSet( wk, &wk->dat->p_data[wk->dat->p_now], _get_page_button_num(wk), 0 );
      BagBmp_WazaInfoClear(wk);

      Bag_ItemMenuExit( wk );

      // メニュー画面を元に戻す
      select_menu_cancel(wk);

      BackButtonOnOffChange( wk, TRUE );

      return SEQ_MAIN;
    }
  }
  return  SEQ_ITEM_REGIST_ERR;

}

//============================================================================================
//  メニュー：解除
//============================================================================================

//--------------------------------------------------------------------------------------------
/**
 * メニュー：とうろく解除
 *
 * @param wk    バッグ画面ワーク
 *
 * @return  次のシーケンス
 */
//--------------------------------------------------------------------------------------------
static int Bag_MenuCnvDel( BAG_WORK * wk )
{
  MyItem_CnvButtonItemDel( wk->myitem, wk->dat->ret_item );

  // 選択肢隠す
  BagObj_SelectPlateDisappear( wk );
  BagBmp_SelectItemClear( wk );
  BagSelectMenu_Clear( &wk->sub_win[ADD_WIN_SELECT0] );
  BagObj_ItemIconSet( wk, &wk->dat->p_data[wk->dat->p_now], _get_page_button_num(wk), 0 );
  BagBmp_WazaInfoClear(wk);

  Bag_ItemMenuExit( wk );

  // メニュー画面を元に戻す
  select_menu_cancel(wk);

  return SEQ_MAIN;
}


//------------------------------------------------------------------
/**
 * @brief   メニュー：どうぐ移動
 *
 * @param   wk
 *
 * @retval  int
 */
//------------------------------------------------------------------
static int Bag_MenuItemMove( BAG_WORK * wk )
{
  // この選択を行えるという事は最初から移動できるどうぐのはず
  ItemChangeInit( wk );
  return SEQ_IREKAE;

}

//============================================================================================
//  メニュー：もたせる
//============================================================================================

//--------------------------------------------------------------------------------------------
/**
 * メニュー：もたせる
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int Bag_MenuSet( BAG_WORK * wk )
{
  Bag_ItemMenuExit( wk );
  BackButtonOnOffChange( wk, FALSE );
  BagObj_CursorDisappear( wk );

  APP_WipeStart( APP_WIPE_OUT, HEAPID_BAG );
  wk->dat->ret_mode = BAG_RET_ITEMSET;  // 終了モード
  return SEQ_OUT;
}


//============================================================================================
//  ポケモンリスト「もたせる」
//============================================================================================

//--------------------------------------------------------------------------------------------
/**
 * ポケモンリストから「もたせる」処理
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int PokeItemSet_MainSeq( BAG_WORK * wk )
{
  int refresh = 0;
  POCKET_DATA *pocket = &wk->dat->p_data[wk->dat->p_now];

  // カーソル移動
  if(sys.repeat & PAD_KEY_UP){
    wk->cursor_pos = _key_table[wk->cursor_pos].up;
    refresh++;
  }else if(sys.repeat & PAD_KEY_DOWN){
    wk->cursor_pos = _key_table[wk->cursor_pos].down;
    refresh++;
  }else if(sys.repeat & PAD_KEY_LEFT){
    if(_key_table[wk->cursor_pos].left==14){
      int result;
      u8 ret;
      result = DecideFunc( wk, CURSORPOS_SUBPAGE, &ret, 0, BAG_PAGE_SELECT, APP_END_KEY);
      if( result != SEQ_MAIN ){
        return result;
      }
      return SEQ_ITEMSET_MAIN;
    }else if( wk->cursor_pos != 16 ){
      if( wk->cursor_pos >= 0 && wk->cursor_pos < BAG_POCKET_NUM ){
        int tmp_pos = _next_pocket( wk, wk->cursor_pos, -1 );
        if( wk->cursor_pos != tmp_pos ){
          wk->cursor_pos = tmp_pos;
          refresh++;
        }
      }else{
        wk->cursor_pos = _key_table[wk->cursor_pos].left;
        refresh++;
      }
    }
  }else if(sys.repeat & PAD_KEY_RIGHT){
    if(_key_table[wk->cursor_pos].right==15){
      int result;
      u8 ret;
      result = DecideFunc( wk, CURSORPOS_ADDPAGE, &ret, 0, BAG_PAGE_SELECT, APP_END_KEY);
      if( result != SEQ_MAIN ){
        return result;
      }
      return SEQ_ITEMSET_MAIN;
    }else if( wk->cursor_pos != 16 ){
      if( wk->cursor_pos >= 0 && wk->cursor_pos < BAG_POCKET_NUM ){
        int tmp_pos = _next_pocket( wk, wk->cursor_pos, 1 );
        if( wk->cursor_pos != tmp_pos ){
          wk->cursor_pos = tmp_pos;
          refresh++;
        }
      }else{
        wk->cursor_pos = _key_table[wk->cursor_pos].right;
        refresh++;
      }
    }
  }else if( sys.trg & PAD_BUTTON_L){
    u8 ret;
    DecideFunc( wk, _next_pocket(wk,wk->dat->p_now,-1), &ret, 1, BAG_PAGE_SELECT, APP_END_KEY);
    return SEQ_ITEMSET_MAIN;
  }else if( sys.trg & PAD_BUTTON_R){
    u8 ret;
    DecideFunc( wk, _next_pocket(wk,wk->dat->p_now,1), &ret, 1, BAG_PAGE_SELECT, APP_END_KEY);
    return SEQ_ITEMSET_MAIN;
  }

  // 移動先が「CURSORPOS_POCKETS」だった場合は現在選択中のポケットに移動させる
  if(wk->cursor_pos==CURSORPOS_POCKETS){
    wk->cursor_pos = wk->dat->p_now;
  }

  // カーソル移動が発生している
  if(refresh){
    Snd_SePlay( BAG_SE_LIST_MOVE1 );
    BgObj_CursorPosAppearSet( wk, wk->cursor_pos );
    // ポケット毎のカーソル位置保存
    _cursor_pos_backup( wk, wk->cursor_pos );
    // アイテム説明描画
    _item_explain_put( wk );
  }

  // アイテム選択
  {
    u8  ret = LIST_SEL_NONE;
    u32 touch;

    // 決定
    if((touch=TouchButtonControl( wk, TOUCH_MODE_NORMAL ))!=RECT_HIT_NONE){
      int result;
      // ページ切り替えの時はカーソルは移動しない
      if( _touch_no_move_check(wk,touch) ){
        if( touch >= 0 && touch < BAG_POCKET_NUM ){
          if( _pocket_search( wk, touch ) != -1 ){
            wk->cursor_pos = touch;
            BgObj_CursorPosAppearSet( wk, wk->cursor_pos );
          }
        }else{
          wk->cursor_pos = touch;
          BgObj_CursorPosAppearSet( wk, wk->cursor_pos );
          if( wk->cursor_pos >= CURSORPOS_ITEM0 && wk->cursor_pos <= CURSORPOS_ITEM5 ){
            _cursor_pos_backup( wk, wk->cursor_pos );
          }
        }
      }
      result = DecideFunc( wk, touch, &ret, 0, BAG_PAGE_SELECT, APP_END_TOUCH);
      if( result!=SEQ_MAIN ){
        wk->dat->ret_mode = BAG_RET_POKEITEMSET;
        return result;
      }
    }else if( sys.trg & PAD_BUTTON_DECIDE ){
      int result = DecideFunc( wk, wk->cursor_pos, &ret, 0, BAG_PAGE_SELECT, APP_END_KEY);
      if( wk->cursor_pos >= CURSORPOS_ITEM0 && wk->cursor_pos <= CURSORPOS_ITEM5 ){
        _cursor_pos_backup( wk, wk->cursor_pos );
      }
      if( result!=SEQ_MAIN ){
        wk->dat->ret_mode = BAG_RET_POKEITEMSET;
        return result;
      }
    }else if( sys.trg & PAD_BUTTON_CANCEL){
      int result = DecideFunc( wk, CURSORPOS_END, &ret, 0, BAG_PAGE_SELECT, APP_END_KEY );
      wk->dat->ret_mode = BAG_RET_POKEITEMSET;
      if( wk->cursor_pos >= CURSORPOS_ITEM0 && wk->cursor_pos <= CURSORPOS_ITEM5 ){
        _cursor_pos_backup( wk, wk->cursor_pos );
      }
      return result;
    }

    if( ret == LIST_SEL_ITEM ){     // 選択された
      if( ItemParamGet( wk->dat->ret_item, ITEM_PRM_EVENT, HEAPID_BAG ) != 0 ||
        ItemPokeAddCheck( wk->dat->ret_item ) == FALSE ){
        STRBUF * str;

        WORDSET_RegisterItemName( wk->wset, 0, wk->dat->ret_item );
        str = MSGMAN_AllocString( wk->msg_man, msg_bag_046 );
        WORDSET_ExpandStr( wk->wset, wk->expb, str );
        STRBUF_Delete( str );
        wk->midx = Bag_TalkMsgPrint( wk, BAG_TALK_FULL );
        wk->dat->ret_mode = BAG_RET_CANCEL;
        return SEQ_ITEMSET_ERR;
      }
      wk->dat->ret_mode = BAG_RET_POKEITEMSET;
      return ButtonAnmSet( wk, ACT_BAG_CURSOR, 41, SEQ_OUT_SET );
    }
  }
  return SEQ_ITEMSET_MAIN;
}

//--------------------------------------------------------------------------------------------
/**
 * ポケモンリストから「もたせる」エラー表示
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int PokeItemSet_ErrorSeq( BAG_WORK * wk )
{
  if( GF_MSG_PrintEndCheck( wk->midx ) == 0 ){
    if( ( sys.trg & (PAD_BUTTON_DECIDE|PAD_BUTTON_CANCEL) ) || sys.tp_trg ){
      BmpTalkWinClear( &wk->win[WIN_TALK], WINDOW_TRANS_OFF );
      GF_BGL_BmpWinOffVReq( &wk->win[WIN_TALK] );
      {
        POCKET_DATA *p = &wk->dat->p_data[wk->dat->p_now];
        BagBmp_ItemNamePrint( wk, p->scr, -1, ITEMPRINT_NORMAL);
      }
      return SEQ_ITEMSET_MAIN;
    }
  }
  return SEQ_ITEMSET_ERR;
}


//============================================================================================
//  売る
//============================================================================================

//--------------------------------------------------------------------------------------------
/**
 * 「売る」モードアイテム選択
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int SaleMainSeq( BAG_WORK * wk )
{
  int refresh = 0;

  // カーソル移動
  if(sys.repeat & PAD_KEY_UP){
    wk->cursor_pos = _key_table[wk->cursor_pos].up;
    refresh++;
  }else if(sys.repeat & PAD_KEY_DOWN){
    wk->cursor_pos = _key_table[wk->cursor_pos].down;
    refresh++;
  }else if(sys.repeat & PAD_KEY_LEFT){
    if(_key_table[wk->cursor_pos].left==14){
      int result;
      u8 ret;
      result = DecideFunc( wk, CURSORPOS_SUBPAGE, &ret, 1, BAG_PAGE_SALE, APP_END_KEY);
      if( result != SEQ_MAIN ){
        return result;
      }
      return SEQ_SALE_MAIN;
    }else if( wk->cursor_pos != 16 ){
      if( wk->cursor_pos >= 0 && wk->cursor_pos < BAG_POCKET_NUM ){
        int tmp_pos = _next_pocket( wk, wk->cursor_pos, -1 );
        if( wk->cursor_pos != tmp_pos ){
          wk->cursor_pos = tmp_pos;
          refresh++;
        }
      }else{
        wk->cursor_pos = _key_table[wk->cursor_pos].left;
        refresh++;
      }
    }
  }else if(sys.repeat & PAD_KEY_RIGHT){
    if(_key_table[wk->cursor_pos].right==15){
      int result;
      u8 ret;
      result = DecideFunc( wk, CURSORPOS_ADDPAGE, &ret, 1, BAG_PAGE_SALE, APP_END_KEY);
      if( result != SEQ_MAIN ){
        return result;
      }
      return SEQ_SALE_MAIN;
    }else if( wk->cursor_pos != 16 ){
      if( wk->cursor_pos >= 0 && wk->cursor_pos < BAG_POCKET_NUM ){
        int tmp_pos = _next_pocket( wk, wk->cursor_pos, 1 );
        if( wk->cursor_pos != tmp_pos ){
          wk->cursor_pos = tmp_pos;
          refresh++;
        }
      }else{
        wk->cursor_pos = _key_table[wk->cursor_pos].right;
        refresh++;
      }
    }
  }else if( sys.trg & PAD_BUTTON_L){
    u8 ret;
    if( wk->cursor_pos >= 0 && wk->cursor_pos < BAG_POCKET_NUM ){
      wk->cursor_pos = _next_pocket( wk, wk->dat->p_now, -1 );
      BgObj_CursorPosAppearSet( wk, wk->cursor_pos );
      DecideFunc( wk, wk->cursor_pos, &ret, 1, BAG_PAGE_SALE, APP_END_KEY);
    }else{
      DecideFunc( wk, _next_pocket(wk,wk->dat->p_now,-1), &ret, 1, BAG_PAGE_SALE, APP_END_KEY);
    }
    return SEQ_SALE_MAIN;
  }else if( sys.trg & PAD_BUTTON_R){
    u8 ret;
    if( wk->cursor_pos >= 0 && wk->cursor_pos < BAG_POCKET_NUM ){
      wk->cursor_pos = _next_pocket( wk, wk->dat->p_now, 1 );
      BgObj_CursorPosAppearSet( wk, wk->cursor_pos );
      DecideFunc( wk, wk->cursor_pos, &ret, 1, BAG_PAGE_SALE, APP_END_KEY);
    }else{
      DecideFunc( wk, _next_pocket(wk,wk->dat->p_now,1), &ret, 1, BAG_PAGE_SALE, APP_END_KEY);
    }
    return SEQ_SALE_MAIN;
  }

  // 移動先が「CURSORPOS_POCKETS」だった場合は現在選択中のポケットに移動させる
  if(wk->cursor_pos==CURSORPOS_POCKETS){
    wk->cursor_pos = wk->dat->p_now;
  }

  // カーソル移動が発生している
  if(refresh){
    Snd_SePlay( BAG_SE_LIST_MOVE1 );
    BgObj_CursorPosAppearSet( wk, wk->cursor_pos );
    // ポケット毎のカーソル位置保存
    _cursor_pos_backup( wk, wk->cursor_pos );
    // アイテム説明描画
    _item_explain_put( wk );
  }

  // アイテム選択
  {
    u8  ret = LIST_SEL_NONE;
    u32 touch;

    // 決定
    if((touch=TouchButtonControl( wk, TOUCH_MODE_NORMAL ))!=RECT_HIT_NONE){
      int result;
      if( _touch_no_move_check(wk,touch) ){
        if( touch >= 0 && touch < BAG_POCKET_NUM ){
          if( _pocket_search( wk, touch ) != -1 ){
            wk->cursor_pos = touch;
            BgObj_CursorPosAppearSet( wk, wk->cursor_pos );
          }
        }else{
          wk->cursor_pos = touch;
          BgObj_CursorPosAppearSet( wk, wk->cursor_pos );
          if( wk->cursor_pos >= CURSORPOS_ITEM0 && wk->cursor_pos <= CURSORPOS_ITEM5 ){
            _cursor_pos_backup( wk, wk->cursor_pos );
          }
        }
      }
      result = DecideFunc( wk, touch, &ret, 1, BAG_PAGE_SALE, APP_END_TOUCH);
      if( result!=SEQ_MAIN ){
        wk->dat->ret_mode = BAG_RET_CANCEL;
        return result;
      }
    }else if( sys.trg & PAD_BUTTON_DECIDE ){
      int result = DecideFunc( wk, wk->cursor_pos, &ret, 1, BAG_PAGE_SALE, APP_END_KEY);
      if( wk->cursor_pos >= CURSORPOS_ITEM0 && wk->cursor_pos <= CURSORPOS_ITEM5 ){
        _cursor_pos_backup( wk, wk->cursor_pos );
      }
      if( result!=SEQ_MAIN ){
        wk->dat->ret_mode = BAG_RET_CANCEL;
        return result;
      }
    }else if(sys.trg & PAD_BUTTON_CANCEL){
      wk->dat->ret_item = 0;
      wk->dat->ret_mode = BAG_RET_CANCEL; // 終了モード
      _set_keytouch_status(wk, APP_END_KEY);
      Snd_SePlay( BAG_SE_CLOSE );
      if( wk->cursor_pos >= CURSORPOS_ITEM0 && wk->cursor_pos <= CURSORPOS_ITEM5 ){
        _cursor_pos_backup( wk, wk->cursor_pos );
      }
      return ButtonPalAnmSet( wk, ACT_BAG_BACK_BUTTON, 9, 8, SEQ_OUT_SET );
    }

    if( ret == LIST_SEL_ITEM ){     // 選択された
      return ButtonAnmSet( wk, ACT_BAG_CURSOR, 41, SEQ_SALE_MENU_INIT );
    }
  }
  return SEQ_SALE_MAIN;
}

//--------------------------------------------------------------------------------------------
/**
 * 「売る」モード個数選択画面初期化
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int SaleMenuInit( BAG_WORK * wk )
{
  STRBUF * str;
  POCKET_DATA *pocket = &wk->dat->p_data[wk->dat->p_now];

  PageSet( wk, BAG_PAGE_SALE, 0, 0 );

  wk->sel_num = 1;
  wk->sel_price = ItemParamGet( wk->dat->ret_item, ITEM_PRM_PRICE, HEAPID_BAG ) >> 1;

  // 表示するどうぐの個数にあわせてカット
  make_button_screen( wk->bgl, GF_BGL_FRAME1_S, 0 );
  GF_BGL_LoadScreenV_Req( wk->bgl, GF_BGL_FRAME1_S );

  // ページ切り替えボタンを隠す
  CATS_ObjectEnableCap( wk->cap[ ACT_BAG_UP_BUTTON ], ACT_OFF );
  CATS_ObjectEnableCap( wk->cap[ ACT_BAG_DOWN_BUTTON ], ACT_OFF );

  // ポケット選択ボタンを隠す
  BagObj_PocketSelectButtonOnOff( wk, ACT_OFF);

  BackButtonOnOffChange( wk, FALSE );

  BagBmp_SelectItemPrint( wk, pocket->scr, wk->cursor_pos-8 );
  BagObj_SelectItemMove( wk, wk->cursor_pos-8 );

  // 選択したどうぐの説明文章を上画面に表示する
  BagBmp_ItemExplainPut( wk, &wk->win[WIN_INFO], wk->dat->ret_item );
  BagObj_CursorDisappear( wk );

  // 大切なもの
  if( ItemParamGet( wk->dat->ret_item, ITEM_PRM_EVENT, HEAPID_BAG ) != 0 || wk->sel_price == 0 ){
    str = MSGMAN_AllocString( wk->msg_man, mes_shop_093 );
    WORDSET_RegisterItemName( wk->wset, 0, wk->dat->ret_item );
    WORDSET_ExpandStr( wk->wset, wk->expb, str );
    STRBUF_Delete( str );
    wk->midx = Bag_TalkMsgPrint( wk, BAG_TALK_FULL );
    return SEQ_SALE_RET;
  }

  Bag_GoldWinPut( wk, 0 );
  Bag_SaleNumWinPut( wk );
  Bag_SubNumPut( wk,NUM_DIGIT_2 );

  // １コしかない
  if( MyItem_GetItemNumDirect(
      wk->dat->p_data[wk->dat->p_now].item,
      wk->dat->p_data[wk->dat->p_now].max, wk->dat->ret_item, HEAPID_BAG ) == 1 ){

    str = MSGMAN_AllocString( wk->msg_man, mes_shop_095 );
    WORDSET_RegisterNumber(
      wk->wset, 0, wk->sel_num*wk->sel_price, 6,
      NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_DEFAULT );
    WORDSET_ExpandStr( wk->wset, wk->expb, str );
    STRBUF_Delete( str );

    wk->midx = Bag_TalkMsgPrint( wk, BAG_TALK_MINI );

    return SEQ_SALE_YN_INIT;
  }
  wk->sel_max   = (u16)pocket->item[pocket->scr+wk->cursor_pos-8].no;   // 所持数

  str = MSGMAN_AllocString( wk->msg_man, mes_shop_094 );
  WORDSET_RegisterItemName( wk->wset, 0, wk->dat->ret_item );
  WORDSET_ExpandStr( wk->wset, wk->expb, str );
  STRBUF_Delete( str );
  wk->midx = Bag_TalkMsgPrint( wk, BAG_TALK_MINI );

  return SEQ_SALE_NUM_INIT;
}



//--------------------------------------------------------------------------------------------
/**
 * 「売る」モード個数選択移行処理
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int SaleNumInitSeq( BAG_WORK * wk )
{
  if( GF_MSG_PrintEndCheck( wk->midx ) == 0 ){
    if( wk->sel_max > 99 ){ wk->sel_max = 99; }

    // 捨てる個数指定へ
    PageSet( wk, BAG_PAGE_SALE, 0, 0 );

    // 数字選択用ボタン表示
    BagObj_SelectCountAppear( wk, NUM_DIGIT_2, wk->sel_max );

    // 「売る」描画
    BagBmp_SalePrint( wk );
    BagBmp_CancelPrint( wk, 1 );

    BagObj_CancelButtonOnOff( wk, ACT_ON );

    // うる用カーソル位置へ
    BagObj_SubCursorPosAppearSet( wk, 0 );

    return SEQ_SALE_NUM_SEL;
  }
  return SEQ_SALE_NUM_INIT;
}

//--------------------------------------------------------------------------------------------
/**
 * 「売る」モード個数選択
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int SaleNumSelSeq( BAG_WORK * wk )
{
  u32 touch,ret=APP_NUMSEL_NONE;

  if((touch=TouchButtonControl( wk, TOUCH_MODE_SALE_NUMBER ))!=RECT_HIT_NONE){
    if(Bag_GetCountButtonPassive( wk->sel_max )==2){
      if(touch==0 || touch==2){
        touch = -1;
      }
    }

    switch(touch){
    case 0:
      wk->sel_num = ItemNumMove( wk->sel_num, wk->sel_max, 10 );
      CATS_ObjectAnimeFrameSetCap( wk->cap[ACT_BAG_NUM_UP0], 0 );
      CATS_ObjectAnimeSeqSetCap( wk->cap[ACT_BAG_NUM_UP0], 26 );
      ret = APP_NUMSEL_UP;
      break;
    case 1:
      wk->sel_num = ItemNumMove( wk->sel_num, wk->sel_max, 1 );
      CATS_ObjectAnimeFrameSetCap( wk->cap[ACT_BAG_NUM_UP1], 0 );
      CATS_ObjectAnimeSeqSetCap( wk->cap[ACT_BAG_NUM_UP1], 26 );
      ret = APP_NUMSEL_UP;
      break;
    case 2:
      wk->sel_num = ItemNumMove( wk->sel_num, wk->sel_max, -10 );
      CATS_ObjectAnimeFrameSetCap( wk->cap[ACT_BAG_NUM_DOWN0], 0 );
      CATS_ObjectAnimeSeqSetCap( wk->cap[ACT_BAG_NUM_DOWN0], 28 );
      ret = APP_NUMSEL_DOWN;
      break;
    case 3:
      wk->sel_num = ItemNumMove( wk->sel_num, wk->sel_max, -1 );
      CATS_ObjectAnimeFrameSetCap( wk->cap[ACT_BAG_NUM_DOWN1], 0 );
      CATS_ObjectAnimeSeqSetCap( wk->cap[ACT_BAG_NUM_DOWN1], 28 );
      ret = APP_NUMSEL_DOWN;
      break;
    case 4:
      ret = APP_NUMSEL_DECIDE;
      break;
    case 5:
      ret = APP_NUMSEL_CANCEL;
      break;
    }
  }else{
    ret=NumSelectCheck( &wk->sel_num, wk->sel_max );
    if(ret==APP_NUMSEL_NONE){
      if( sys.trg & PAD_BUTTON_DECIDE ){
        ret = APP_NUMSEL_DECIDE;
      }else if( sys.trg & PAD_BUTTON_CANCEL ){
        ret = APP_NUMSEL_CANCEL;
      }
    }
  }

  switch( ret ){
  case APP_NUMSEL_NONE:
    break;
  case APP_NUMSEL_UP:
    Bag_SaleNumWinPut( wk );
    Bag_SubNumPut(wk, NUM_DIGIT_2);
    Snd_SePlay( SEQ_SE_DP_BAG_004 );
    return SEQ_SALE_NUM_SEL;

  case APP_NUMSEL_DOWN:
    Bag_SaleNumWinPut( wk );
    Bag_SubNumPut(wk, NUM_DIGIT_2);
    Snd_SePlay( SEQ_SE_DP_BAG_004 );
    return SEQ_SALE_NUM_SEL;

  case APP_NUMSEL_DECIDE:
    Snd_SePlay( BAG_SE_ITEM_SELECT );
    return ButtonPalAnmSet( wk, ACT_BAG_BUTTON_SELL_DOPOSIT, 9, 8, SEQ_SALE_NUM_ENTER );

  case APP_NUMSEL_CANCEL:
    Snd_SePlay( BAG_SE_CLOSE );
    return ButtonPalAnmSet( wk, ACT_BAG_BACK_BUTTON, 9, 8, SEQ_SALE_NUM_CANCEL );
  }

  return SEQ_SALE_NUM_SEL;
}

//--------------------------------------------------------------------------------------------
/**
 * 売る個数決定
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int SeqSaleNumEnter( BAG_WORK * wk )
{
  STRBUF * str;

  BmpMenuWinClear( &wk->win[WIN_SALE_NUM], WINDOW_TRANS_OFF );
  BagBmp_DepositSaleClear( wk );
  GF_BGL_BmpWinDataFill( &wk->win[WIN_TALK], 15 );
  str = MSGMAN_AllocString( wk->msg_man, mes_shop_095 );
  WORDSET_RegisterNumber(
    wk->wset, 0, wk->sel_num*wk->sel_price, 6,
    NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_DEFAULT );
  WORDSET_ExpandStr( wk->wset, wk->expb, str );
  STRBUF_Delete( str );
  wk->midx = Bag_TalkMsgPrint( wk, BAG_TALK_MINI );
  BagObj_SelectCountDisappear( wk );
  BagObj_CursorDisappear(wk);
  BackButtonOnOffChange( wk, FALSE );
  return SEQ_SALE_YN_INIT;
}

//--------------------------------------------------------------------------------------------
/**
 * 売る個数選択キャンセル
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int SeqSaleNumCancel( BAG_WORK * wk )
{
  STRBUF * str;

  wk->sel_price = 0;
  BmpMenuWinClear( &wk->sub_win[ADD_WIN_GOLD], WINDOW_TRANS_OFF );
  BmpMenuWinClear( &wk->win[WIN_SALE_NUM], WINDOW_TRANS_OFF );
  BmpTalkWinClear( &wk->win[WIN_TALK], WINDOW_TRANS_OFF );
  GF_BGL_BmpWinOffVReq( &wk->win[WIN_TALK] );
  GF_BGL_BmpWinOnVReq( &wk->win[WIN_INFO] );
  BagObj_SelectCountDisappear( wk );
  BagObj_CursorDisappear(wk);

  BagObj_ItemIconSet( wk, &wk->dat->p_data[wk->dat->p_now], _get_page_button_num(wk), 0 );
  BagBmp_WazaInfoClear(wk);
  Bag_ItemMenuExit( wk );
  // メニュー画面を元に戻す
  select_menu_cancel(wk);

  BagObj_PocketSelectButtonOnOff( wk, ACT_ON );

  BackButtonOnOffChange( wk, TRUE );

  return SEQ_SALE_MAIN;
}


//--------------------------------------------------------------------------------------------
/**
 * 「売る」はい・いいえ初期化
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int SaleYesNoInitSeq( BAG_WORK * wk )
{
  if( GF_MSG_PrintEndCheck( wk->midx ) == 0 ){
    Bag_YesNoSelInit( wk );
    return SEQ_SALE_YN_SEL;
  }
  return SEQ_SALE_YN_INIT;
}

//--------------------------------------------------------------------------------------------
/**
 * 「売る」はい・いいえ
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int SaleYesNoSelectSeq( BAG_WORK * wk )
{
  u32 ret;

  ret = TOUCH_SW_Main( wk->tss );

  switch( ret ){
  case TOUCH_SW_RET_YES:
    Bag_YesNoSelEnd( wk );
    {
      STRBUF * str = MSGMAN_AllocString( wk->msg_man, mes_shop_096 );
      WORDSET_RegisterItemName( wk->wset, 0, wk->dat->ret_item );
      WORDSET_RegisterNumber(
        wk->wset, 1, wk->sel_num*wk->sel_price, 6,
        NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_DEFAULT );
      WORDSET_ExpandStr( wk->wset, wk->expb, str );
      STRBUF_Delete( str );
    }
    wk->midx = Bag_TalkMsgPrint( wk, BAG_TALK_FULL );
    return SEQ_SALE_CMP;

  case BMPMENU_NULL:
    break;

  case TOUCH_SW_RET_NO:
    Bag_YesNoSelEnd( wk );
    wk->sel_price = 0;
    // お金ウインドウ消去
    BmpMenuWinClear( &wk->sub_win[ADD_WIN_GOLD], WINDOW_TRANS_OFF );
    // 会話ウインドウ消去
    BmpTalkWinClear( &wk->win[WIN_TALK], WINDOW_TRANS_OFF );
    GF_BGL_BmpWinOffVReq( &wk->win[WIN_TALK] );
    GF_BGL_BmpWinOnVReq( &wk->win[WIN_INFO] );

    BagObj_ItemIconSet( wk, &wk->dat->p_data[wk->dat->p_now], _get_page_button_num(wk), 0 );
    BagBmp_WazaInfoClear(wk);
    Bag_ItemMenuExit( wk );

    // メニュー画面を元に戻す
    select_menu_cancel(wk);

    BagObj_PocketSelectButtonOnOff( wk, ACT_ON );

    BackButtonOnOffChange( wk, TRUE );

    return SEQ_SALE_MAIN;
  }
  return SEQ_SALE_YN_SEL;
}

//--------------------------------------------------------------------------------------------
/**
 * 「売る」完了
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int SaleCmpSeq( BAG_WORK * wk )
{
  if( GF_MSG_PrintEndCheck( wk->midx ) != 0 ){
    return SEQ_SALE_CMP;
  }

  Snd_SePlay( SEQ_SE_DP_REGI );
  Mystatus_AddGold( wk->myst, wk->sel_num*wk->sel_price );
  if( wk->sel_num == 1 ){
    if( wk->dat->fnote_sale_cnt != 0xff ){
      wk->dat->fnote_sale_cnt++;
    }
  }else{
    wk->dat->fnote_sale_cnt = 2;
  }

  // どうぐの削除＆リスト再構築
  MyItem_SubItemDirect(
    wk->dat->p_data[wk->dat->p_now].item,
    wk->dat->p_data[ wk->dat->p_now ].max,
    wk->dat->ret_item, wk->sel_num, HEAPID_BAG );
  ItemListDataMake( wk );

  GF_BGL_BmpWinOnVReq( &wk->win[WIN_TALK] );

  return SEQ_SALE_RET;
}

//--------------------------------------------------------------------------------------------
/**
 * 「売る」メッセージ終了待ち＆ボタン待ち -> メインへ
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int SaleRetSeq( BAG_WORK * wk )
{
  if( GF_MSG_PrintEndCheck( wk->midx ) == 0 ){
    if( ( sys.trg & (PAD_BUTTON_DECIDE|PAD_BUTTON_CANCEL) ) || sys.tp_trg ){
      wk->sel_price = 0;
      BmpMenuWinClear( &wk->sub_win[ADD_WIN_GOLD], WINDOW_TRANS_OFF );
      BmpTalkWinClear( &wk->win[WIN_TALK], WINDOW_TRANS_OFF );
      GF_BGL_BmpWinOffVReq( &wk->win[WIN_TALK] );
      GF_BGL_BmpWinOnVReq( &wk->win[WIN_INFO] );

      BagObj_ItemIconSet( wk, &wk->dat->p_data[wk->dat->p_now], _get_page_button_num(wk), 1 );
      BagBmp_WazaInfoClear(wk);
      Bag_ItemMenuExit( wk );

      // メニュー画面を元に戻す
      select_menu_cancel(wk);
      // 説明再描画
      _item_explain_put( wk );

      // ポケット選択ボタンを戻す
      BagObj_PocketSelectButtonOnOff( wk, ACT_ON );

      BackButtonOnOffChange( wk, TRUE );

      return SEQ_SALE_MAIN;
    }
  }
  return SEQ_SALE_RET;
}


//============================================================================================
//  木の実関連
//============================================================================================

//--------------------------------------------------------------------------------------------
/**
 * 木の実選択モードメイン
 *
 * @param wk    バッグ画面のワーク
 *
 * @return  移行するメインシーケンス
 */
//--------------------------------------------------------------------------------------------
static int KinomiSel_MainSeq( BAG_WORK * wk )
{
  // ポケット選択（十字キー）
  if( PocketControl( wk ) == TRUE ){
    return SEQ_PAGE;
  }

  // アイテム選択
  {
    u8  ret = LIST_SEL_NONE;

    if( ret == LIST_SEL_ITEM ){     // 選択された
      if( wk->dat->p_data[wk->dat->p_now].type == BAG_POKE_NORMAL ){
        if( ItemParamGet(wk->dat->ret_item,ITEM_PRM_FIELD,HEAPID_BAG) != ITEMUSE_FLD_KOYASHI ){
          BAG_ItemUseErrorMsgSet(
            wk->myst, wk->expb, wk->dat->ret_item, ITEMCHECK_FALSE, HEAPID_BAG );
          wk->midx = Bag_TalkMsgPrint( wk, BAG_TALK_FULL );
          return SEQ_ITEM_ERR_WAIT;
        }
      }
      wk->dat->ret_mode = BAG_RET_USE;
      APP_WipeStart( APP_WIPE_OUT, HEAPID_BAG );
      return SEQ_OUT;
    }else if( ret == LIST_SEL_CANCEL ){ // キャンセル
      wk->dat->ret_mode = BAG_RET_CANCEL;
      return SEQ_OUT;
    }
  }
  return SEQ_KINOMISEL_MAIN;
}


//============================================================================================
//  木の実プランター用
//============================================================================================

//--------------------------------------------------------------------------------------------
/**
 * 木の実プランター用「つかう」処理
 *
 * @param wk    バッグ画面ワーク
 *
 * @return  次のシーケンス
 */
//--------------------------------------------------------------------------------------------
static int Bag_MenuPlanterUse( BAG_WORK * wk )
{
  Bag_ItemMenuExit( wk );
  BackButtonOnOffChange( wk, FALSE );
  BagObj_CursorDisappear( wk );

  APP_WipeStart( APP_WIPE_OUT, HEAPID_BAG );
  wk->dat->ret_mode = BAG_RET_POKEITEMSET;  // 終了モード（木の実プランターがこれを見てるので。）
  return SEQ_OUT;
}

//--------------------------------------------------------------------------------------------
/**
 * @brief 木の実プランター用使用チェック
 *
 * @param pocket  ポケット番号
 * @param item  アイテム番号
 *
 * @retval  "TRUE = 使えます"
 * @retval  "FALSE = それ以外"
 */
//--------------------------------------------------------------------------------------------
BOOL BAGMAIN_NPlanterUseCheck( u16 pocket, u16 item )
{
  if( pocket == BAG_POKE_NUTS ||
    ( item >= COMPOST_START_ITEMNUM && item < (COMPOST_START_ITEMNUM+ITEM_COMPOST_MAX) ) ){
    return TRUE;
  }
  return FALSE;
}


//------------------------------------------------------------------
/**
 * @brief   BG面のカラーを切り替える
 *
 * @param   wk    バッグ画面ワーク
 * @param   type
 * @param   no
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void BAG_BackGroundPalChange( BAG_WORK *wk, int type, int no )
{
  u16 *paldata = wk->bgPalPtr[type]->pRawData;
  if(no>7){
    return;
  }

  // 一列目はメインBG
  GXS_LoadBGPltt( &paldata[no*16], 0,    16*2);
  GXS_LoadBGPltt( &paldata[no*16], 32, 16*2*2);

  //
  GXS_LoadBGPltt( &paldata[no*16], 96,   16*2);
}

#define ORDER_NONE    ( 0 )
#define ORDER_PASTE   ( 1 )
#define ORDER_CUT     ( 2 )

typedef struct{
  u8 command;         // ORDER_NONE, ORDER_PASTE(領域内でコピペ), ORDER_CUT（削除）
  u8 cx, cy, px, py, w, h;  // コピー開始XY,コピー先XY,横幅,縦幅
  u8 dummy;
}CUT_PASTE_DATA;

#define BG_ORDER_MAX  ( 4 )

/// スクリーンの切り貼りを行うためのコマンドテーブル
static CUT_PASTE_DATA bg_cutpaste_tbl[][BG_ORDER_MAX]={
  {
    { ORDER_NONE,  0,  0, 0, 0,  0, 0, },{ ORDER_CUT,   0,  0, 0, 4,32,16,  },
    { ORDER_NONE,  0,  0, 0, 0,  0, 0, },{ ORDER_NONE,  0,  0,16, 4,16,16,  },
  },

  { // 1
    { ORDER_PASTE, 0, 19, 0, 9, 16, 1, },{ ORDER_CUT,   0,  0, 0,10,16,10,  },
    { ORDER_NONE,  0,  0, 0, 0,  0, 0, },{ ORDER_CUT,   0,  0,16, 4,16,16,  },
  },
  { // 2
    { ORDER_PASTE, 0, 19, 0, 9, 16, 1, },{ ORDER_NONE,  0,  0, 0, 0, 0, 0,  },
    { ORDER_PASTE,16, 19,16, 9, 16, 1, },{ ORDER_CUT,   0,  0, 0,10,32,10,  },
  },
  { // 3
    { ORDER_PASTE, 0, 19, 0,14, 16, 1, },{ ORDER_CUT,   0,  0, 0,15,16, 5,  },
    { ORDER_PASTE,16, 19,16, 9, 16, 1, },{ ORDER_CUT,   0,  0,16,10,16,10,  },
  },
  { // 4
    { ORDER_PASTE, 0, 19, 0,14, 16, 1, },{ ORDER_NONE,  0,  0, 0, 0, 0, 0,  },
    { ORDER_PASTE,16, 19,16,14, 16, 1, },{ ORDER_CUT,   0,  0, 0,15,32, 5,  },
  },
  { // 5
    { ORDER_NONE,  0,  0, 0, 0,  0, 0, },{ ORDER_NONE,  0,  0, 0, 0, 0, 0,  },
    { ORDER_PASTE,16, 19,16,14, 16, 1, },{ ORDER_CUT,   0,  0,16,15,16, 5,  },
  },
};


//------------------------------------------------------------------
/**
 * @brief   ボタン面を切り貼りする
 *
 * @param   bgl
 * @param   frm
 * @param   num   どうぐの数
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void make_button_screen( GF_BGL_INI *bgl, int frm, int num )
{
  u16 *buf = GF_BGL_ScreenAdrsGet( bgl, frm );
  int  i;

  if(num==6){
    return;
  }

  for(i=0;i<BG_ORDER_MAX;i++){
    CUT_PASTE_DATA *cpd = &bg_cutpaste_tbl[num][i];
    if(cpd->command==ORDER_PASTE){
      // 指定部分をコピペ
      GF_BGL_ScrWrite( bgl, frm, &buf[cpd->cy*32+cpd->cx], cpd->px, cpd->py, cpd->w, cpd->h);
    }else if(cpd->command==ORDER_CUT){
      // 指定矩形をカット
      GF_BGL_ScrFill( bgl, frm, 0, cpd->px, cpd->py, cpd->w, cpd->h, 0 );
    }
  }
}


// --------------------------------------------------------------
// どうぐ移動画面構築の際のBG加工用テーブル
// --------------------------------------------------------------
typedef struct{
  u8 cx, cy, w, h;
}INSERT_CUT_DATA;

#define INSERT_CUT_W ( 16 )
#define INSERT_CUT_H (  4 )
#define INSERT_COMMAND_NUM  ( 2 )

static INSERT_CUT_DATA insert_page_tbl[][INSERT_COMMAND_NUM]={
  { {  0, 11, 16, 9}, { 16, 6, 16, 16 },  },  // どうぐが1つ
  { {  0, 11, 32, 9}, {  0, 0,  0,  0 },  },  // どうぐが2
  { {  0, 16, 16, 4}, { 16,11, 16,  9 },  },  // どうぐが3
  { {  0, 16, 32, 4}, {  0, 0,  0,  0 },  },  // どうぐが4
  { {  0,  0,  0, 0}, { 16,16, 16,  4 },  },  // どうぐが5
                          // 6つのときはカットする必要がない
};

static INSERT_CUT_DATA insert_win_tbl[]={
  { 0, 4, 16, 6 },  { 16, 4, 16, 6  },
  { 0, 9, 16, 6 },  { 16, 9, 16, 6  },
  { 0,14, 16, 6 },  { 16,14, 16, 6  },

};

//------------------------------------------------------------------
/**
 * @brief   どうぐ移動画面のBG加工処理
 *
 * @param   bgl
 * @param   frm
 * @param   num   どうぐの数
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void make_insert_button_screen( GF_BGL_INI *bgl, int frm, int num, int target )
{
  u16 *buf = GF_BGL_ScreenAdrsGet( bgl, frm );
  INSERT_CUT_DATA *win;
  int i;

  for(i=0;i<INSERT_COMMAND_NUM;i++){
    INSERT_CUT_DATA *icd = &insert_page_tbl[num-1][i];
    // 指定矩形をカット
    GF_BGL_ScrFill( bgl, frm, 0, icd->cx, icd->cy, icd->w, icd->h, 0 );
  }

  // ページ内に移動する道具がない
  if( target == -1 ){ return; }

  win = &insert_win_tbl[target];

  // どうぐ移動対象だけはウインドウの形が変わらない
  if(target==0 || target==1){
    GF_BGL_ScrWrite( bgl, frm, &buf[24*32],  win->cx, win->cy,  win->w, win->h);
  }else{
    GF_BGL_ScrWrite( bgl, frm, &buf[27*32], win->cx, win->cy, win->w, win->h);
  }

}
//------------------------------------------------------------------
/**
 * @brief   背景セットを行う
 *
 * @param   wk    バッグ画面ワーク
 * @param   page  BAG_PAGE_NORMAL, BAG_PAGE_INSERT
 * @param   num   表示するどうぐ総数
 * @param   target  どうぐ移動モードの時の対象
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void PageSet( BAG_WORK *wk, int page, int num, int target )
{
  NNSG2dScreenData *scrnData;
  void       *scrnBuf;

  GF_ASSERT(  page==BAG_PAGE_NORMAL || page==BAG_PAGE_INSERT ||
        page==BAG_PAGE_SELECT || page==BAG_PAGE_SUB    || page==BAG_PAGE_SALE);

  // 通常ページの場合
  switch(page){
  case BAG_PAGE_NORMAL:

    // ボタン面セット(一旦６つボタンのスクリーンを読み込む）
    scrnBuf = ArcUtil_ScrnDataGet(ARC_BAG_GRA, NARC_bag_gra_itemBG03_d_nscr,0, &scrnData, HEAPID_BAG);
    GF_BGL_ScreenBufSet( wk->bgl, GF_BGL_FRAME1_S, scrnData->rawData, scrnData->szByte );
    DC_FlushRange( GF_BGL_ScreenAdrsGet( wk->bgl, GF_BGL_FRAME1_S ), scrnData->szByte );

    // 表示するどうぐの個数にあわせてカット
    make_button_screen( wk->bgl, GF_BGL_FRAME1_S, num );

    GF_BGL_LoadScreenV_Req( wk->bgl, GF_BGL_FRAME1_S );
    sys_FreeMemoryEz(scrnBuf);

    // 背景面セット
//    ArcUtil_ScrnSet(  ARC_BAG_GRA, NARC_bag_gra_itemBG01_d_nscr, wk->bgl, GF_BGL_FRAME2_S, 0, 0, 0, HEAPID_BAG );
    scrnBuf = ArcUtil_ScrnDataGet(ARC_BAG_GRA, NARC_bag_gra_itemBG01_d_nscr,0, &scrnData, HEAPID_BAG);
    GF_BGL_ScreenBufSet( wk->bgl, GF_BGL_FRAME2_S, scrnData->rawData, scrnData->szByte );
    GF_BGL_LoadScreenV_Req( wk->bgl, GF_BGL_FRAME2_S );
    sys_FreeMemoryEz(scrnBuf);

    // どうぐ移動用タグは表示しない
    BagObj_InsertTagSet( wk, 0, 0, 0 );
    break;


  // どうぐ移動ページの場合
  case BAG_PAGE_INSERT:
    // ボタン面セット(一旦６つボタンのスクリーンを読み込む）
    scrnBuf = ArcUtil_ScrnDataGet(ARC_BAG_GRA, NARC_bag_gra_itemBG04_d_nscr,0, &scrnData, HEAPID_BAG);
    GF_BGL_ScreenBufSet( wk->bgl, GF_BGL_FRAME1_S, scrnData->rawData, scrnData->szByte );
    DC_FlushRange( GF_BGL_ScreenAdrsGet( wk->bgl, GF_BGL_FRAME1_S ), scrnData->szByte );

    // 表示するどうぐの個数にあわせてカット
    make_insert_button_screen( wk->bgl, GF_BGL_FRAME1_S, num, target );

    GF_BGL_LoadScreenV_Req( wk->bgl, GF_BGL_FRAME1_S );
    sys_FreeMemoryEz(scrnBuf);


    // 背景面セット
//    ArcUtil_ScrnSet(  ARC_BAG_GRA, NARC_bag_gra_itemBG02_d_nscr, wk->bgl, GF_BGL_FRAME2_S, 0, 0, 0, HEAPID_BAG );
    scrnBuf = ArcUtil_ScrnDataGet(ARC_BAG_GRA, NARC_bag_gra_itemBG02_d_nscr,0, &scrnData, HEAPID_BAG);
    GF_BGL_ScreenBufSet( wk->bgl, GF_BGL_FRAME2_S, scrnData->rawData, scrnData->szByte );
    GF_BGL_LoadScreenV_Req( wk->bgl, GF_BGL_FRAME2_S );
    sys_FreeMemoryEz(scrnBuf);

    // 選択肢を全て隠す
    BagObj_SelectPlateDisappear( wk );

    // どうぐ移動用タグの表示
    BagObj_InsertTagSet( wk, num, _get_inpage_target( wk ), 0 );

    OS_Printf("入れ替えどうぐは  %d\n", _get_inpage_target( wk ));
    break;


  // どうぐ選択時
  case BAG_PAGE_SELECT:
//    ArcUtil_ScrnSet( ARC_BAG_GRA, NARC_bag_gra_itemBG05_d_nscr, wk->bgl, GF_BGL_FRAME2_S, 0, 0, 0, HEAPID_BAG );
    scrnBuf = ArcUtil_ScrnDataGet(ARC_BAG_GRA, NARC_bag_gra_itemBG05_d_nscr,0, &scrnData, HEAPID_BAG);
    GF_BGL_ScreenBufSet( wk->bgl, GF_BGL_FRAME2_S, scrnData->rawData, scrnData->szByte );
    GF_BGL_LoadScreenV_Req( wk->bgl, GF_BGL_FRAME2_S );
    sys_FreeMemoryEz(scrnBuf);
    // 表示するどうぐの個数にあわせてカット
    make_button_screen( wk->bgl, GF_BGL_FRAME1_S, num );
    GF_BGL_LoadScreenV_Req( wk->bgl, GF_BGL_FRAME1_S );
    break;

  // 捨てる
  case BAG_PAGE_SUB:
//    ArcUtil_ScrnSet( ARC_BAG_GRA, NARC_bag_gra_itemBG06_d_nscr, wk->bgl, GF_BGL_FRAME2_S, 0, 0, 0, HEAPID_BAG );
    scrnBuf = ArcUtil_ScrnDataGet(ARC_BAG_GRA, NARC_bag_gra_itemBG06_d_nscr,0, &scrnData, HEAPID_BAG);
    GF_BGL_ScreenBufSet( wk->bgl, GF_BGL_FRAME2_S, scrnData->rawData, scrnData->szByte );
    GF_BGL_LoadScreenV_Req( wk->bgl, GF_BGL_FRAME2_S );
    sys_FreeMemoryEz(scrnBuf);
    break;

  // 売る
  case BAG_PAGE_SALE:
//    ArcUtil_ScrnSet( ARC_BAG_GRA, NARC_bag_gra_itemBG07_d_nscr, wk->bgl, GF_BGL_FRAME2_S, 0, 0, 0, HEAPID_BAG );
    scrnBuf = ArcUtil_ScrnDataGet(ARC_BAG_GRA, NARC_bag_gra_itemBG07_d_nscr,0, &scrnData, HEAPID_BAG);
    GF_BGL_ScreenBufSet( wk->bgl, GF_BGL_FRAME2_S, scrnData->rawData, scrnData->szByte );
    GF_BGL_LoadScreenV_Req( wk->bgl, GF_BGL_FRAME2_S );
    sys_FreeMemoryEz(scrnBuf);
    break;
  }
}


//------------------------------------------------------------------
/**
 * @brief   キータッチ状態の設定（NULLの時は代入しない）
 *
 * @param   wk
 * @param   key_touch
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void _set_keytouch_status( BAG_WORK *wk, int key_touch )
{
  // NULLでなければキータッチ状態を入力する
  if(wk->dat->kt_status!=NULL){
    KeyTouchStatus_SetTouchOrKey( wk->dat->kt_status, key_touch );
  }

}


//--------------------------------------------------------------------------------------------
/**
 * キャンセルボタン表示切替
 *
 * @param   wk    バッグ画面ワーク
 * @param   flg   TRUE = 表示, FALSE = 非表示
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void BackButtonOnOffChange( BAG_WORK * wk, BOOL flg )
{
  if( flg == TRUE ){
    BagObj_CancelButtonOnOff( wk, ACT_ON );
    BagBmp_CancelPrint( wk, 0 );
    GF_BGL_BmpWinOnVReq( &wk->win[WIN_CANCEL] );
    CATS_ObjectAnimeFrameSetCap( wk->cap[ACT_BAG_BACK_BUTTON], 0 );
    CATS_ObjectAnimeSeqSetCap( wk->cap[ACT_BAG_BACK_BUTTON], 16 );
  }else{
    BagObj_CancelButtonOnOff( wk, ACT_OFF );
    BagBmp_CancelOff( wk );
  }
}

//--------------------------------------------------------------------------------------------
/**
 * ボタンパレットアニメセット
 *
 * @param   wk    バッグ画面ワーク
 * @param id    OBJ ID
 * @param   pal1  パレット１
 * @param   pal2  パレット２
 * @param   next  アニメ後のシーケンス
 *
 * @return  次のシーケンス
 */
//--------------------------------------------------------------------------------------------
static int ButtonPalAnmSet( BAG_WORK * wk, u8 id, u8 pal1, u8 pal2, int next )
{
  BAG_BUTTON_ANM_WORK * bawk = &wk->button_anm_work;

  bawk->mode = BUTTON_ANM_MODE_PAL;
  bawk->id   = id;
  bawk->pal1 = pal1;
  bawk->pal2 = pal2;
  bawk->next = next;

  bawk->seq = 0;
  bawk->cnt = 0;

  return SEQ_BUTTON_ANM;
}

//--------------------------------------------------------------------------------------------
/**
 * ボタンアニメセット
 *
 * @param   wk    バッグ画面ワーク
 * @param id    OBJ ID
 * @param   anm   アニメ番号
 * @param   next  アニメ後のシーケンス
 *
 * @return  次のシーケンス
 */
//--------------------------------------------------------------------------------------------
static int ButtonAnmSet( BAG_WORK * wk, u8 id, u8 anm, int next )
{
  BAG_BUTTON_ANM_WORK * bawk = &wk->button_anm_work;

  bawk->mode = BUTTON_ANM_MODE_ANM;
  bawk->id   = id;
  bawk->next = next;

  bawk->seq = 0;
  bawk->cnt = 0;

  CATS_ObjectAnimeFrameSetCap( wk->cap[id], 0 );
  CATS_ObjectAnimeSeqSetCap( wk->cap[id], anm );

  return SEQ_BUTTON_ANM;
}

//--------------------------------------------------------------------------------------------
/**
 * ボタンアニメメイン
 *
 * @param   wk    バッグ画面ワーク
 *
 * @return  次のシーケンス
 */
//--------------------------------------------------------------------------------------------
static int ButtonAnmMain( BAG_WORK * wk )
{
  BAG_BUTTON_ANM_WORK * bawk = &wk->button_anm_work;

  if( bawk->mode == BUTTON_ANM_MODE_ANM ){
    if( CATS_ObjectAnimeActiveCheckCap(wk->cap[bawk->id]) == FALSE ){
      return bawk->next;
    }
  }else{
    switch( bawk->seq ){
    case 0:
      CATS_ObjectPaletteSetCap( wk->cap[bawk->id], bawk->pal1 );
      bawk->seq++;
      break;

    case 1:
      bawk->cnt++;
      if( bawk->cnt != 4 ){ break; }
      CATS_ObjectPaletteSetCap( wk->cap[bawk->id], bawk->pal2 );
      bawk->cnt = 0;
      bawk->seq++;
      break;

    case 2:
      bawk->cnt++;
      if( bawk->cnt == 2 ){
        return bawk->next;
      }
    }
  }

  return SEQ_BUTTON_ANM;
}









//============================================================================================
//============================================================================================
//============================================================================================
//============================================================================================
//  ３Ｄ
//============================================================================================
//============================================================================================
#define BAG3D_CAMERA_NEAR ( 123 * FX32_ONE )    // カメラ・ニアクリップ
#define BAG3D_CAMERA_FAR  ( 1700 * FX32_ONE )   // カメラ・ファークリップ

static void Load3DData( BAG_WORK * wk );
static void Delete3DData( BAG_WORK * wk );

// カメラデータ
#ifdef DEBUG_CAMERA
static GF_CAMERA_PARAM CameraParam = {
  0x153b51,             // 距離
  { 0xe982, 0x1420, 0x0 },        // アングル
  GF_CAMERA_PERSPECTIV,       // 射影
  0xa01,                // パース
  0,                  // dummy
};

static VecFx32 model_trans = {0,-184320,0};

#else
static const GF_CAMERA_PARAM CameraParam = {
  0x153b51,             // 距離
  { 0xe982, 0x1420, 0x0 },      // アングル
  GF_CAMERA_PERSPECTIV,       // 射影
  0xa01,                // パース
  0,                  // dummy
};
static const VecFx32 model_trans = {0,-184320,0};
#endif

static const VecFx32 Bag3DCameraTarget = { 0, 0, 0 }; // カメラ注視点



//--------------------------------------------------------------------------------------------
/**
 * ３Ｄ初期化
 *
 * @param wk    バッグ画面ワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void Init3D( BAG_WORK * wk )
{
  simple_3DBGInit( HEAPID_BAG );

//  G3X_AlphaTest( FALSE, 0 );
//  G3X_AlphaBlend( TRUE );
  G3X_AntiAlias( TRUE );


  G3X_SetFog( FALSE, 0, 0, 0 );
  G3X_SetClearColor( 0, 0, 0x7fff, 0, FALSE );

  // ディフューズ、アンビエント設定
  NNS_G3dGlbMaterialColorDiffAmb(
    GX_RGB(15,15,15),
    GX_RGB(10,10,10),
    FALSE );
  // スペキュラ・エミッション設定
  NNS_G3dGlbMaterialColorSpecEmi(
    GX_RGB(15,15,15),
    GX_RGB(15,15,15),
    FALSE );



  NNS_G3dGlbPolygonAttr(
    0x0f,
    GX_POLYGONMODE_MODULATE,
    GX_CULL_NONE,
    0,
    31,
    0 );

  G3X_EdgeMarking( TRUE );
  G3X_SetEdgeColorTable(gEdgeColor);  // エッジマーキングテーブルセット

  GF_BGL_PrioritySet( GF_BGL_FRAME0_M, 0 );
  GF_Disp_GX_VisibleControl( GX_PLANEMASK_BG0, TRUE );

  // カメラ作成
  wk->wk3d.camera = GFC_AllocCamera( HEAPID_BAG );
  wk->wk3d.target = Bag3DCameraTarget;

  wk->wk3d.camera_param = CameraParam;
  GFC_InitCameraTDA(
    &wk->wk3d.target,
    wk->wk3d.camera_param.Distance, // 距離
    &wk->wk3d.camera_param.Angle,
    wk->wk3d.camera_param.PerspWay, // 投射影の角度
    wk->wk3d.camera_param.View,
    TRUE,
    wk->wk3d.camera );

  wk->wk3d.model_trans = model_trans;

  // カメラ移動ルーチン初期化
  CameraMoveInit( &wk->wk3d );
  // 現在のポケットの位置に向かう
  CameraMoveStart( &wk->wk3d, wk->dat->p_now+1, CAMERA_MOVE_FRAME );

  GFC_SetCameraClip( BAG3D_CAMERA_NEAR, BAG3D_CAMERA_FAR, wk->wk3d.camera );
  GFC_AttachCamera( wk->wk3d.camera );

  // ライト


  {
    u32 i;

    for( i=0; i<4; i++ ){
      NNS_G3dGlbLightVector( i, FX16_ONE, 0, 0 );
      NNS_G3dGlbLightColor( i, 0x7fff );
    }
  }

  // シーンデータ
  Load3DData( wk );

  GF_Disp_GX_VisibleControl( GX_PLANEMASK_BG0, VISIBLE_ON );
    G2_SetBG0Priority( 2 );


}


//------------------------------------------------------------------
/**
 * @brief   カメラ移動ルーチン初期化
 *
 * @param   wk
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void CameraMoveInit( BAG_3D_WORK *wk )
{
  wk->inter[0]  = 0;
  wk->inter[1]  = 0;
  wk->inter[2]  = CAMERA_NO_MOVE;
  wk->frame     = CAMERA_MOVE_FRAME;
  wk->frame_max = CAMERA_MOVE_FRAME;
}

//------------------------------------------------------------------
/**
 * @brief   次のバッグ位置への移動開始設定
 *
 * @param   BAG_3D_WORK
 * @param   移動先のカメラ位置INDEX
 * @param   CAMERA_MOVE_FRAME
 *
 * @retval  none
 */
//------------------------------------------------------------------
static  void CameraMoveStart( BAG_3D_WORK *wk, int next, int frame )
{
  // カメラ移動が発生していない時の代入
  if(wk->frame==wk->frame_max){
    wk->inter[0]   = wk->inter[1];
    wk->inter[1]   = next;
    wk->frame    = 0;
    wk->frame_max  = frame;
  }else{
    wk->inter[2] = next;
  }
}



//------------------------------------------------------------------
/**
 * @brief   カメラ位置補間処理
 *
 * @param   &wk->wk3D
 *
 * @retval  none
 */
//------------------------------------------------------------------
static void CameraModelMove( BAG_3D_WORK *wk3d, int sex )
{
  const CAMERA_MODEL_POSITION *cmp = bag_camera_data[sex];
  fx32 x,y,d,my,wx1,sign;
  if(wk3d->frame!=wk3d->frame_max){
    wk3d->frame++;

    // xだけ30度から-30のあたりを動くので計算が細かい
    wx1 = MATH_ABS(cmp[wk3d->inter[1]].angle.x-cmp[wk3d->inter[0]].angle.x);
    // 回転方向の算出
    if(cmp[wk3d->inter[1]].angle.x<cmp[wk3d->inter[0]].angle.x){
      sign = -1;
    }else{
      sign = 1;
    }
    // 180度以上の回転の場合は移動角度が最小になるように反転させる（移動方向も）
    if(wx1>0x8000){
      wx1 = 0x10000 - wx1;
      sign *= -1;
    }

    // 回転
    if(sign>0){
      x  = cmp[wk3d->inter[0]].angle.x  + wx1/wk3d->frame_max*wk3d->frame;
    }else{
      x  = cmp[wk3d->inter[0]].angle.x  - wx1/wk3d->frame_max*wk3d->frame;
    }
    OS_Printf("angle x=%x\n",x);

    // 他の値は同じ値の範囲で移動するので素直に計算してよい
    y  = cmp[wk3d->inter[0]].angle.y  + (cmp[wk3d->inter[1]].angle.y-cmp[wk3d->inter[0]].angle.y)/wk3d->frame_max*wk3d->frame;
    d  = cmp[wk3d->inter[0]].distance + (cmp[wk3d->inter[1]].distance-cmp[wk3d->inter[0]].distance)/wk3d->frame_max*wk3d->frame;
    my = cmp[wk3d->inter[0]].model_y  + (cmp[wk3d->inter[1]].model_y-cmp[wk3d->inter[0]].model_y)/wk3d->frame_max*wk3d->frame;
    wk3d->camera_param.Angle.x  = x;
    wk3d->camera_param.Angle.y  = y;
    wk3d->camera_param.Distance = d;
    wk3d->model_trans.y = my;
  }

  // カメラ移動が予約されている時の処理
  if(wk3d->frame==wk3d->frame_max){
    if(wk3d->inter[2]!=CAMERA_NO_MOVE){
      wk3d->inter[0] = wk3d->inter[1];
      wk3d->inter[1] = wk3d->inter[2];
      wk3d->inter[2] = -1;
      wk3d->frame = 0;
    }
  }
}


//--------------------------------------------------------------------------------------------
/**
 * ３Ｄ解放
 *
 * @param wk    バッグ画面ワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void Exit3D( BAG_WORK * wk )
{
  Delete3DData( wk );
  GFC_FreeCamera( wk->wk3d.camera );
  simple_3DBGExit();
}


//--------------------------------------------------------------------------------------------
/**
 * ３Ｄ描画
 *
 * @param wk    バッグ画面ワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void Draw3DMain( BAG_WORK * wk )
{
  BAG3D_SCENE_DATA * scene;

  // 描画
  MtxFx33 rotate_tmp = {FX32_ONE,0,0,0,FX32_ONE,0,0,0,FX32_ONE};
  VecFx32 scale = {FX32_ONE,FX32_ONE,FX32_ONE};

#ifdef DEBUG_CAMERA
  if(sys.cont&PAD_BUTTON_R){
    if(sys.cont&PAD_KEY_UP){
      wk->wk3d.camera_param.Angle.x -= 0x100;
      OS_Printf("angle x = %x, angle y = %x, distance = %x, model_y = %d\n",
        wk->wk3d.camera_param.Angle.x,wk->wk3d.camera_param.Angle.y, wk->wk3d.camera_param.Distance, wk->wk3d.model_trans.y);
    }else if(sys.cont&PAD_KEY_DOWN){
      wk->wk3d.camera_param.Angle.x += 0x100;
      OS_Printf("angle x = %x, angle y = %x, distance = %x, model_y = %d\n",
        wk->wk3d.camera_param.Angle.x,wk->wk3d.camera_param.Angle.y, wk->wk3d.camera_param.Distance, wk->wk3d.model_trans.y);
    }else if(sys.cont&PAD_KEY_LEFT){
      wk->wk3d.camera_param.Angle.y -= 0x100;
      OS_Printf("angle x = %x, angle y = %x, distance = %x, model_y = %d\n",
        wk->wk3d.camera_param.Angle.x,wk->wk3d.camera_param.Angle.y, wk->wk3d.camera_param.Distance, wk->wk3d.model_trans.y);
    }else if(sys.cont&PAD_KEY_RIGHT){
      wk->wk3d.camera_param.Angle.y += 0x100;
      OS_Printf("angle x = %x, angle y = %x, distance = %x, model_y = %d\n",
        wk->wk3d.camera_param.Angle.x,wk->wk3d.camera_param.Angle.y, wk->wk3d.camera_param.Distance, wk->wk3d.model_trans.y);
    }else if(sys.cont&PAD_BUTTON_X){
      wk->wk3d.camera_param.Distance -= 0x1000;
      OS_Printf("angle x = %x, angle y = %x, distance = %x, model_y = %d\n",
        wk->wk3d.camera_param.Angle.x,wk->wk3d.camera_param.Angle.y, wk->wk3d.camera_param.Distance, wk->wk3d.model_trans.y);
    }else if(sys.cont&PAD_BUTTON_Y){
      wk->wk3d.camera_param.Distance += 0x1000;
      OS_Printf("angle x = %x, angle y = %x, distance = %x, model_y = %d\n",
        wk->wk3d.camera_param.Angle.x,wk->wk3d.camera_param.Angle.y, wk->wk3d.camera_param.Distance, wk->wk3d.model_trans.y);
    }else if(sys.cont&PAD_BUTTON_SELECT){
      model_trans.y -= -FX32_ONE;
      wk->wk3d.model_trans.y = model_trans.y;
      OS_Printf("angle x = %x, angle y = %x, distance = %x, model_y = %d\n",
        wk->wk3d.camera_param.Angle.x,wk->wk3d.camera_param.Angle.y, wk->wk3d.camera_param.Distance, wk->wk3d.model_trans.y);
    }else if(sys.cont&PAD_BUTTON_START){
      model_trans.y += -FX32_ONE;
      wk->wk3d.model_trans.y = model_trans.y;
      OS_Printf("angle x = %x, angle y = %x, distance = %x, model_y = %d\n",
        wk->wk3d.camera_param.Angle.x,wk->wk3d.camera_param.Angle.y, wk->wk3d.camera_param.Distance, wk->wk3d.model_trans.y);
    }
  }

#endif

  // カメラ位置補間処理
  CameraModelMove( &wk->wk3d, wk->sex );

  // カメラ適用
  GFC_InitCameraTDA(
    &wk->wk3d.target,
    wk->wk3d.camera_param.Distance, // 距離
    &wk->wk3d.camera_param.Angle,
    wk->wk3d.camera_param.PerspWay, // 投射影の角度
    wk->wk3d.camera_param.View,
    TRUE,
    wk->wk3d.camera );

  GF_G3X_Reset();
  GFC_CameraLookAt();

  // 各アニメーションのフレームを進める
  scene = &wk->wk3d.scene;
  AnimationFrameAdd( scene->itpObj[scene->anmNum] );
  AnimationFrameAdd( scene->icaObj[scene->anmNum] );
  AnimationFrameAdd( scene->itaObj );

  simple_3DModelDraw(
    &scene->rendObj,
    &wk->wk3d.model_trans,
    &rotate_tmp,
    &scale );

//  GF_G3_RequestSwapBuffers( GX_SORTMODE_AUTO, GX_BUFFERMODE_W );
  GF_G3_RequestSwapBuffers( GX_SORTMODE_AUTO, GX_BUFFERMODE_Z );
}


//----------------------------------------------------------------------------------
/**
 * 各アニメーションOBJのフレームを進める(ループ再生）
 *
 * @param   obj
 */
//----------------------------------------------------------------------------------
static void AnimationFrameAdd( NNSG3dAnmObj *obj )
{

  if( obj->frame+FX32_ONE < NNS_G3dAnmObjGetNumFrame(obj) ){
    obj->frame += FX32_ONE;
  }else{
    obj->frame = 0;
  }
}
//--------------------------------------------------------------------------------------------
/**
 * ３Ｄモデル作成
 *
 * @param wk    バッグ画面ワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void Load3DData( BAG_WORK * wk )
{
  ARCHANDLE * ah;
  BAG3D_SCENE_DATA * scene;
  NNSG3dResTex * tex;
  void * anmRes;
  u32 model, itp, ica, ita;
  u32 i;

  ah = ArchiveDataHandleOpen( ARC_BAG_GRA, HEAPID_BAG );

  sys_InitAllocator( &wk->wk3d.allocator, HEAPID_BAG, 4 );

  scene = &wk->wk3d.scene;

  if( wk->sex == 0 ){
    model = NARC_bag_gra_m_model_nsbmd;
    itp   = NARC_bag_gra_m_on1_nsbtp;
    ica   = NARC_bag_gra_m_on1_nsbca;
    ita   = NARC_bag_gra_m_ef_nsbta;
  }else{
    model = NARC_bag_gra_f_model_nsbmd;
    itp   = NARC_bag_gra_f_on1_nsbtp;
    ica   = NARC_bag_gra_f_on1_nsbca;
    ita   = NARC_bag_gra_f_ef_nsbta;
  }

  // モデリングデータをロード
  scene->rh = ArchiveDataLoadAllocByHandle( ah, model, HEAPID_BAG );

  simple_3DModelSetResFileAlready( &scene->rendObj, &scene->mdl, &scene->rh );
  tex = NNS_G3dGetTex( scene->rh ); // テクスチャリソース取得
//  BindTexture( scene->rh, tex );

  NNS_G3dMdlUseMdlDiff( scene->mdl );   // ディフューズ
  NNS_G3dMdlUseMdlAmb( scene->mdl );    // アンビエント
  NNS_G3dMdlUseMdlSpec( scene->mdl );   // スペキュラー
  NNS_G3dMdlUseMdlEmi( scene->mdl );    // エミッション
  NNS_G3dMdlUseMdlPolygonID( scene->mdl );

  // アニメーションをロード
  for( i=0; i<BAG3D_ANM_MAX; i++ ){

    // itp
    scene->anmMem[i] = ArchiveDataLoadAllocByHandle( ah, itp+i, HEAPID_BAG );
    anmRes = NNS_G3dGetAnmByIdx( scene->anmMem[i], 0 );
    // 必要量のメモリをアロケート
    scene->itpObj[i] = NNS_G3dAllocAnmObj(
              &wk->wk3d.allocator,    // 使用するアロケータを指定
              anmRes,       // アニメーションリソースを指定
              scene->mdl );   // モデルリソースを指定
    // イニシャライズ
    NNS_G3dAnmObjInit(
      scene->itpObj[i], // アニメーションオブジェクトへのポインタ
      anmRes,       // アニメリソースへのポインタ
      scene->mdl,     // NNSG3dResMdlへのポインタ
      tex );        // NNSG3dResTexへのポインタ

    // ica
    scene->icaMem[i] = ArchiveDataLoadAllocByHandle( ah, ica+i, HEAPID_BAG );
    anmRes = NNS_G3dGetAnmByIdx( scene->icaMem[i], 0 );
    // 必要量のメモリをアロケート
    scene->icaObj[i] = NNS_G3dAllocAnmObj(
              &wk->wk3d.allocator,    // 使用するアロケータを指定
              anmRes,       // アニメーションリソースを指定
              scene->mdl );   // モデルリソースを指定
    // イニシャライズ
    NNS_G3dAnmObjInit(
      scene->icaObj[i], // アニメーションオブジェクトへのポインタ
      anmRes,       // アニメリソースへのポインタ
      scene->mdl,     // NNSG3dResMdlへのポインタ
      tex );        // NNSG3dResTexへのポインタ


  }
  // itp
  scene->itaMem = ArchiveDataLoadAllocByHandle( ah, ita, HEAPID_BAG );
  anmRes = NNS_G3dGetAnmByIdx( scene->itaMem, 0 );
  // 必要量のメモリをアロケート
  scene->itaObj = NNS_G3dAllocAnmObj(
            &wk->wk3d.allocator,    // 使用するアロケータを指定
            anmRes,       // アニメーションリソースを指定
            scene->mdl );   // モデルリソースを指定
  // イニシャライズ
  NNS_G3dAnmObjInit(
    scene->itaObj,  // アニメーションオブジェクトへのポインタ
    anmRes,       // アニメリソースへのポインタ
    scene->mdl,     // NNSG3dResMdlへのポインタ
    tex );        // NNSG3dResTexへのポインタ


  // アニメ割り当て
  scene->anmNum = wk->dat->p_now;
  NNS_G3dRenderObjAddAnmObj( &scene->rendObj, scene->itpObj[scene->anmNum] );
  NNS_G3dRenderObjAddAnmObj( &scene->rendObj, scene->icaObj[scene->anmNum] );
  NNS_G3dRenderObjAddAnmObj( &scene->rendObj, scene->itaObj );

  sys_PrintHeapFreeSize(HEAPID_BAG);

  ArchiveDataHandleClose( ah );
}

//--------------------------------------------------------------------------------------------
/**
 * ３Ｄモデル削除
 *
 * @param wk    バッグ画面ワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void Delete3DData( BAG_WORK * wk )
{
  BAG3D_SCENE_DATA * scene;
  u32 i;

  scene = &wk->wk3d.scene;

  // アニメーション削除
  for( i=0; i<BAG3D_ANM_MAX; i++ ){
    NNS_G3dFreeAnmObj( &wk->wk3d.allocator, scene->itpObj[i] );
    NNS_G3dFreeAnmObj( &wk->wk3d.allocator, scene->icaObj[i] );
    sys_FreeMemoryEz( scene->anmMem[i] );
    sys_FreeMemoryEz( scene->icaMem[i] );
  }
  NNS_G3dFreeAnmObj( &wk->wk3d.allocator, scene->itaObj );
  sys_FreeMemoryEz( scene->itaMem );

  // テクスチャーリソース削除
  sys_FreeMemoryEz( scene->rh );
}

//--------------------------------------------------------------------------------------------
/**
 * 上画面のバッグ３Ｄモデルのアニメ切り替え
 *
 * @param wk    バッグ画面ワーク
 *
 * @return  none
 */
//--------------------------------------------------------------------------------------------
static void Bag3DObjAnmChg( BAG_WORK * wk )
{
  BAG3D_SCENE_DATA * scene = &wk->wk3d.scene;

  NNS_G3dRenderObjRemoveAnmObj( &scene->rendObj, scene->icaObj[scene->anmNum] );
  NNS_G3dRenderObjRemoveAnmObj( &scene->rendObj, scene->itpObj[scene->anmNum] );

  scene->anmNum = wk->dat->p_now;

  scene->itpObj[scene->anmNum]->frame = 0;
  scene->icaObj[scene->anmNum]->frame = 0;
  scene->itaObj->frame = 0;
  NNS_G3dRenderObjAddAnmObj( &scene->rendObj, scene->itpObj[scene->anmNum] );
  NNS_G3dRenderObjAddAnmObj( &scene->rendObj, scene->icaObj[scene->anmNum] );
}